Log in

View Full Version : Softice Breakpoints


JRoger
March 20th, 2005, 10:17
Ive got Compuware Driver Studio 3.1 on my Win XP SP2 computer. It works great, and I can use:

addr process
bpx 00440000

or whatever and softice pops up great.
But I cant understand why softice wont pop up when I set breakpoints on windows api calls.

Firstly I added the EXP=.....user32.dll lines in winice.dat
and then when i set bpx MessageBoxA, and type BL
it recognises it as 00) BPX USER32!MessageBoxA. But, however many MessageBoxA I execute it wont pop up.

Then I try the symbol retriever, grab the symbols, load them into softice, comment out the EXP= lines in winice.dat and set another breakpoint.
The same thing happens, it recognises MessageBoxA as User32, but it just wont pop up.

So many tutorials tell me to do bpx GetDlgItemTextA and softice will pop up, but it wont... Im gettin so frustrated, any help would be greatly appreciated.

John

naides
March 20th, 2005, 10:43
Quote:
[Originally Posted by JRoger]but it wont... Im gettin so frustrated, any help would be greatly appreciated.
John


Relax, Roger. Breath. . . Don't get frustrated.

Chances are you set the bpx MessageBoxA while you are standing on a different address context than the app that you intend to generate the API call. . .

If you place a bpx MessageBoxA while standing on the ADDR context of application A, you will only break when Application A (or any of its modules) calls MessageBoxA.

If app B or any other app but A calls MessageBoxA, Sice will not break!

Search the board and learn the Sice setup command to disable this behavoir.

Better: Address context specific BPXs are actually GOOD. Before the ADDR context thingy, every time I placed a BPX on GetSystemTime, Sice would break relentlessly on every fucking app in the system tray that called this API, meaning all of them, 10 times per second. So I could never get to the code of interest.
It is better to set up the BP effectively to derive maximum advantage from them.

JRoger
March 20th, 2005, 18:51
I just tried bpx GetSystemTime just now, still nothing. I dont know whether this is normal, but as soon as ive set the breakpoint, if i type BL, it gives me _GetSystemTime. If i have to wait a while before it shows Kernel32!GetSystemTime. The problem is not Softice breaking too often (I would be delighted if it did), but its more that it wont break at all!

I have tried doing ADDR targetapp, and making the app run my breakpoint, but softice refuses to break. Why???

BTW, what is your init string for Soft Ice?

JRoger
March 20th, 2005, 19:13
DOH, im sorry guys. A simple case of RTFM, or even the FAQ on the forum...
For anyone else with this problem, use the command "Set BreakInSharedMods ON", and hurray, problem solved.

Sorry for the time-wasting

evlncrn8
March 20th, 2005, 21:01
wasnt the bpx.p and bpx.t meant for the context specific stuff?

Kayaker
March 21st, 2005, 20:12
Hi

I think the subtleties are in how they are all used. The .p and .t qualifiers make the breakpoints conditional on the PID or TID, literally adding IF statements. "BPX.p eip" is transformed to "BPX eip IF (PID==0xXXX)".

What defines context? Context can be considered a fairly broad term I suppose, which includes both process and thread identifiers, and everything that they define, structures, addresses, etc., etc. How Softice defines context may be seen in how it handles the BreakInSharedMods setting.

There is a global variable, dCurrentContext, which is used in many places in Softice code when comparing or switching context. It is actually a pointer to the current KPROCESS structure, or KPEB as Sice names it, identifiable by the 0x1B in the 1st dword of the structure:
Code:
0000 KPROCESS struc ; (sizeof=0x6c)
0000 Header DISPATCHER_HEADER ? ; DO_TYPE_PROCESS (0x1B)
0010 ProfileListHead LIST_ENTRY ?
0018 DirectoryTableBase dd ?
001C PageTableBase dd ?
0020 LdtDescriptor KGDTENTRY ?
0028 Int21Descriptor KIDTENTRY ?
0030 IopmOffset dw ?
0032 Iopl db ?
0033 VdmFlag db ?
0034 ActiveProcessors dd ?
0038 KernelTime dd ?
003C UserTime dd ?
0040 ReadyListHead LIST_ENTRY ?
0048 SwapListEntry LIST_ENTRY ?
0050 ThreadListHead LIST_ENTRY ? ; KTHREAD.ThreadListEntry
0058 ProcessLock dd ?
005C Affinity dd ?
0060 StackCount dw ?
0062 BasePriority db ?
0063 ThreadQuantum db ?
0064 AutoAlignment db ?
0065 State db ?
0066 ThreadSeed db ?
0067 DisableBoost db ?
0068 PowerState db ?
0069 DisableQuantum db ?
006A Spare db 2 dup(?)
006C KPROCESS ends

As far as Softice is generally concerned, a pointer to this structure is what defines "context".


Here's a small snippet from a portion of breakpoint setup code in Softice where BreakInSharedMods is used. The code cycles through the array of TDJF breakpoint structures that have been defined, testing and setting some of the fields. (see my previous posts on TDJF Breakpoint Table structure if interested).

SET BreakInSharedMods ON, is used to set non context-sensitive breakpoints in shared ring3 modules (for system dll APIs basically). If the BreakInSharedMods flag is OFF (non global), a pointer to the *current* KPROCESS structure is added to the rest of the information in the breakpoint table, limiting the breakpoint to only that process context.
Code:
_loop:
...
:000A0F36 80 BB D3 EB 11 00 03 cmp TDJF.Breakpoint_Type[ebx], 3 ;
:000A0F36 ; BPINT = 01h
:000A0F36 ; BPM/BPIO = 03h
:000A0F36 ; BPX = 05h
:000A0F36 ; BMSG = 06h
:000A0F3D 75 5C jnz short NextTDJF

:000A0F3F 8A 83 DE EB 11 00 mov al, TDJF.Breakpoint_Mode[ebx] ;
:000A0F3F ; execute = 0
:000A0F3F ; write = 1
:000A0F3F ; read = 2
:000A0F3F ; read/write = 3
:000A0F45 24 03 and al, 3
:000A0F47 3C 02 cmp al, 2
:000A0F49 74 50 jz short NextTDJF

:000A0F4B 42 inc edx
:000A0F4C 80 3D 96 8A 10 00 01 cmp BreakInSharedMods_dbFlag, 1
:000A0F53 74 13 jz short @BreakInSharedMods_ON

; specify current context (pointer to KPROCESS) for this breakpoint
:000A0F55 60 pusha
:000A0F56 8B 83 D6 EB 11 00 mov eax, TDJF.BPAddress_1[ebx]
:000A0F5C E8 AD 77 FA FF call GetCurrentContext ; KPROCESS
:000A0F61 89 83 02 EC 11 00 mov TDJF.CurrentContext[ebx], eax
:000A0F67 61 popa

:000A0F68 @BreakInSharedMods_ON:
...

NextTDJF:
:00A0F9B 81 C3 78 01 00 00 add ebx, 178h ; sizeof TDJF
:000A0FA1 49 dec ecx
:000A0FA2 0F 85 44 FF FF FF jnz _loop



I hope this is suitably esoteric Softice information, harmful in mass quantities.. ;-)

Cheers,
Kayaker

bilbo
March 22nd, 2005, 03:53
Great, Kayaker!

I just would add that the code is taken from DriverStudio 3.1, and I would add some more defines for breakpoint types:
Code:

:000A0F36 ; BPINT = 01h
:000A0F36 ; BPM/BPIO = 03h
:000A0F36 ; BPX = 05h
:000A0F36 ; BMSG = 06h


IMO, in field TDJF.Breakpoint_Type, we can find:
Code:

0=free, 1=BPINT, 2=BPIO, 3=BPM, 4=BPR, 5=BPX, 6=BMSG, 7=BPTE


Best regards, bilbo

naides
March 22nd, 2005, 08:03
Yes, right, Kayaker and Bilbo. That is what I wanted to say, in other words

Kayaker
March 22nd, 2005, 21:08
Thanks bilbo, now that you mention it, for DS 3.2 the Breakpoint_Type for BPIO is indeed = 2. However, I do see a difference in DS 3.1, where Breakpoint_Type = 3 for both BPIO and BPMx. This can be seen in live testing (staring fixedly at the Breakpoint Table while changing BP's), or from the code, certain parts of which are identical:

Code:
DS 3.1
BPM
:000A3F3E loc_A3F3E: ; CODE XREF: c_Bpm+284j
:000A3F3E B0 03 mov al, 3 ; Breakpoint_Type
:000A3F40 E8 73 06 00 00 call TDJF_Checkfor_DuplicateBP
:000A3F45 72 29 jb short _retn
:000A3F47 66 0F B3 0D 94 1B 12 00 btr word_121B94, cx
:000A3F4F 80 C9 80 or cl, 80h
:000A3F52 88 8B D5 EB 11 00 mov TDJF.DRx_Register[ebx], cl
:000A3F58 C6 83 D3 EB 11 00 03 mov TDJF.Breakpoint_Type[ebx], 3


BPIO
:000A41CF loc_A41CF: ; CODE XREF: c_Bpio+102j
:000A41CF B0 03 mov al, 3 ; Breakpoint_Type
:000A41D1 E8 E2 03 00 00 call TDJF_Checkfor_DuplicateBP
:000A41D6 72 1D jb short _retn
:000A41D8 66 0F B3 0D 94 1B 12 00 btr word_121B94, cx
:000A41E0 80 C9 80 or cl, 80h
:000A41E3 88 8B D5 EB 11 00 mov TDJF.DRx_Register[ebx], cl
:000A41E9 C6 83 D3 EB 11 00 03 mov TDJF.Breakpoint_Type[ebx], 3


As you mentioned, this has changed in DS 3.2.

BPT? Lol, I had to look that one up, I guess I never use it though I might now. Um, you are right there is a ref. to an unknown BP type "7" somewhere in the beepee code (cmp and ignore), but I can't see that it's BPT. The command itself simply dumps an existing BP into the command line for editing into a new BP. Checking it visually, the new BP (next free TDJF structure) then takes on whatever BreakPoint_Type is required, not specifically 7. Do you have secret info?

As for BPR, we are all saddened it went the way of Win9x and the Dodo..

Just like naides said

K.

TQN
March 22nd, 2005, 21:28
Great analysis, Kayaker and bilbo.
I have learnt many things from you. It is a good idea to reverse SoftIce.

bilbo
March 23rd, 2005, 04:19
Quote:
[Originally Posted by TQN]It is a good idea to reverse SoftIce.
I agree... but don't speak so loud, someone thinks it is illegal, like coca!

Kayaker, I indeed had not yet time/money/will to look at DS3.2...
So let's go on with DS3.1:

I based my assertion on sub_A45B8 (which you call TDJF_Checkfor_DuplicateBP) where the code which checks duplicated BPIO's is separated from the code which checks for other duplicated breakpoints
Code:

loc_A45E9:
mov esi, dword_11EBD6[edx] ; bkstruct+7: address / number

cmp al, 2 ; BPIO
jz short loc_A4619 ; checks for duplicated BPIO
cmp al, 6 ; BMSG
jz short loc_A4623 ; checks for duplicated BMSG
cmp al, 7 ; BPTE
jz short loc_A4667 ; continue in loop: skip checks for duplicated BPTE
; checks follow for duplicated BPX/BPM/BPINT


but especially from sub_A30D6, which decodes the different breakpoint types
Code:

sub_A30D6 proc

movzx eax, byte_11EBD3[ebx] ; bkstruct+4: bkstruct type
cmp eax, 0
jz short loc_A3156 ; return CY if free

pusha
push edi
dec eax ; set type origin to 0
; strcpy_(ESI=from, EDI=to)
lea esi, aBpint[eax*8]
call sub_6E540

where aBpint is an array defined as "char aBpint[7][8]", 8 bytes per breakpoint type:
Code:

aBpint:
db 'BPINT ',0,0,0 ; type 1
db 'BPIO ',0,0,0 ; type 2
db 'BPM ',0,0,0,0 ; type 3
db 'BPR ',0,0,0,0 ; type 4
db 'BPX ',0,0,0,0 ; type 5
db 'BMSG ',0,0,0 ; type 6
db 'BPTE ',0,0 ; type 7


No secret info, as you see, things are simpler than they seem
And you are right: on a practical point of view BPIO(2), BPR and BPTE are just defined but not used.

Best regards, bilbo

P.S: I hope I have not annoyed or disgusted someone on the board...

Kayaker
March 23rd, 2005, 17:47
Aha! You do have secret info!!

You are definitely right Bilbo, there is an unused BPTE command! I should have looked closer at the strings, I'm ashamed of myself . I thought your BPTE might have been a typo, but I didn't really believe you would make a mistake. The error messages are interesting:

Code:

.data:00111D11
db 'BPTE KTEB [IF expresssion] - Ring 3 threads only!',0

:000A659E
db 'BPTE: Invalid command line. Try BPTE { KTEB }',0
db 'BPTE: Invalid command line. You must specify a thread.',0
db 'BPTE: Invalid command line. Try BPTE { KTEB }',0
db 'Unable to find thread %x',0
db 'Unable to find process %x',0


The unused command prologue:
:000A37BA BE A2 F7 10 00 mov esi, offset bUserCommand
:000A37BF 56 push esi
:000A37C0 E8 A7 2E 00 00 call _BPTE
:000A37C5 C3 retn


It's a very extensive command. Maybe for future use, break on thread entry? Of course you realize I have to try to run it now... I'll be back after the crash ;-)

Regards,
Kayaker