Using softice isnt just bpx hmemcpy


Written by NoodleSpa

Reason: /me tired of stupid questions about theese tings

Tools:

Lets say you wanna put a breakpoint but nothing hits :~( or you find that you just wanna scan for some string or data, well this is a better way to do it than the regular bpx whatever and then s 030:0 l ffffffff 'blah' we will use mIRC32 as an example.

Command: map32
Usage: map32 mirc32
Output: :map32 mirc32 Owner Obj Name Obj# Address Size Type MIRC32 CODE 0001 0157:00401000 000F0000 CODE RO MIRC32 DATA 0002 015F:004F1000 00035000 IDATA RW MIRC32 .tls 0003 015F:00526000 00001000 IDATA RW MIRC32 .rdata 0004 015F:00527000 00001000 IDATA RO SHARED MIRC32 .INIT 0005 015F:00528000 00002000 IDATA RO MIRC32 .idata 0006 015F:0052A000 00001000 IDATA RW MIRC32 .edata 0007 015F:0052B000 00001000 IDATA RO MIRC32 .reloc 0008 015F:0052C000 00016000 IDATA RO SHARED MIRC32 .rsrc 0009 015F:00542000 0002D000 IDATA RW SHARED

This gives us a listing of the sections in the .exe and what kind they are and where the process is mapped in virtual memory.

We want this because we don't wanna waste time searching the entire address space - we can see that the process starts at 401000 and ends at 542000 + 2d000 (we have to add the size of the last section to know exactly how long it is). A small note is that the process actually starts at 400000 but there is a 1000 byte header section at its beginning which is not included in the softice output.

we find out the length by typing this in softice:
:? 542000+2d000
0056F000 0005697536 "V "

the output is 0056F000 wich is the address at which the process ends we then substract the so called imagebase (which is where the process actually starts, and that is at 00400000) like this:

:? 56f000-400000
0016F000 0001503232 "_ "

We now have the length of the process and it is 0016F000

But we aren't in the correct context, and what is a context you might ask... well all processes (and even threads) have their own context, a context is like an environment, in this environment there are of course the CPU registers you see at the top of softice (EAX EBX and so on), and there is also 4 Gb of address space. Now you may wonder how all processes can have their own 4 gigabytes of space, it doesnt really make sense now does it :)

Well they can becasue of something called Virtual Machines and Virtual Address space. The process doesn't really have 4Gb until it actually demands it, and most processes never do that because it would slow down the computer a bit, and its also quite hard to make use of such a vast amount of space.(f0dder note: no it is not ;)

I wont go into this now becuse this is the minitut, but i might write about it later. (f0dder note: look at intel's pentium3 documents, look for "paging"). For now we are happy to have learned the map32 command and how to use the softice calculator. But you should know that every virtual machine (process or thread that is running) has its own context, which is simply a number or name if you will that windows use to keep track of what each register in that particular process/thread contains. Each process also has a handle and an ID and a thread also has a handle and an ID. All of this is mainatined by windows so it can keep track of each process and what it is doing.

The proc command is also very nice.
Command: proc
Usage: proc mirc32
Output: :proc mirc32 Process pProcess ProcessID Threads Context DefHeap DebuggeeCB Mirc32 8180B9F0 FF03AEDD 00000003 C10D2B50 00570000 00000000

You can see that this also give a lot of info on the process, what we are interested in is the context handle. we are gonna use it to view a context (the one that mirc32 is in) without actually breaking into mirc32 with a breakpoint. for this we use a different command:

Addr
Usage: Addr contexthandle processname :addr c10d2b50 mirc32

You have to do the proc command before this otherwise you wont have a correct context handle, the context handle will be different every time you run mIRC32.

Now do this in softice: d 400000

If you look at your data window you will see that it says mIRC32

now type u 401000
you will now see the code section of mIRC32 in your code window softice will look kinda like this: EAX=00000004 EBX=CE520070 ECX=00000000 EDX=00001862 ESI=C1094F80 EDI=C00034C0 EBP=CE179F70 ESP=CE179DA0 EIP=C0008CF8 o d I s Z a P c CS=0028 DS=0030 SS=0030 ES=0030 FS=0078 GS=0030 -----MIRC32---------------------------------------byte--------------PROT---(0)-- 0030:00400000 4D 5A 50 00 02 00 00 00-04 00 0F 00 FF FF 00 00 MZP............. 0030:00400010 B8 00 00 00 00 00 00 00-40 00 1A 00 00 00 00 00 ........@....... 0030:00400020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0030:00400030 00 00 00 00 00 00 00 00-00 00 00 00 00 01 00 00 ................ 0030:00400040 BA 10 00 0E 1F B4 09 CD-21 B8 01 4C CD 21 90 90 ........!..L.!.. 0030:00400050 54 68 69 73 20 70 72 6F-67 72 61 6D 20 6D 75 73 This program mus 0030:00400060 74 20 62 65 20 72 75 6E-20 75 6E 64 65 72 20 57 t be run under W 0030:00400070 69 6E 33 32 0D 0A 24 37-00 00 00 00 00 00 00 00 in32..$7........ -------------------------------------------------------------------------PROT32- 0028:00401000 A163104F00 MOV EAX,[004F1063] 0028:00401005 C1E002 SHL EAX,02 0028:00401008 A367104F00 MOV [004F1067],EAX 0028:0040100D 57 PUSH EDI 0028:0040100E 51 PUSH ECX 0028:0040100F 33C0 XOR EAX,EAX 0028:00401011 BFEC185000 MOV EDI,005018EC 0028:00401016 B964595200 MOV ECX,00525964 0028:0040101B 3BCF CMP ECX,EDI 0028:0040101D 7605 JBE 00401024 0028:0040101F 2BCF SUB ECX,EDI 0028:00401021 FC CLD 0028:00401022 F3AA REPZ STOSB 0028:00401024 59 POP ECX 0028:00401025 5F POP EDI 0028:00401026 6A00 PUSH 00 0028:00401028 E81A0D0000 CALL 00401D47 0028:0040102D 59 POP ECX 0028:0040102E 682C104F00 PUSH 004F102C 0028:00401033 6A00 PUSH 00 0028:00401035 E835F60E00 CALL KERNEL32!GetModuleHandleA 0028:0040103A A36B104F00 MOV [004F106B],EAX 0028:0040103F 6A00 PUSH 00 0028:00401041 E9D6C90000 JMP 0040DA1C 0028:00401046 E9970D0000 JMP 00401DE2 0028:0040104B 33C0 XOR EAX,EAX ------------------------------------MIRC32!CODE---------------------------------

Now type: :s 400000 l 16f000 'Borland' and this will appear in your data window: -----MIRC32!DATA----------------------------------byte--------------PROT---(0)-- 0030:004F1000 42 6F 72 6C 61 6E 64 20-43 2B 2B 20 2D 20 43 6F Borland C++ - Co 0030:004F1010 70 79 72 69 67 68 74 20-31 39 39 36 20 42 6F 72 pyright 1996 Bor 0030:004F1020 6C 61 6E 64 20 49 6E 74-6C 2E 00 00 00 18 50 00 land Intl.....P. 0030:004F1030 60 18 50 00 60 18 50 00-90 18 50 00 01 00 00 00 `.P.`.P...P..... 0030:004F1040 00 00 00 00 98 37 4A 00-04 20 42 00 2C 20 42 00 .....7J.. B., B. 0030:004F1050 00 00 00 00 BC 00 50 00-00 EC 10 50 00 84 11 50 ......P....P...P 0030:004F1060 00 00 01 00 00 00 00 00-00 00 00 00 00 40 00 00 .............@.. 0030:004F1070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

Now this is nice, let us try to expand a little on this trick, type map32 mIRC32 and you wil get the same list as above Owner Obj Name Obj# Address Size Type MIRC32 CODE 0001 0157:00401000 000F0000 CODE RO MIRC32 DATA 0002 015F:004F1000 00035000 IDATA RW MIRC32 .tls 0003 015F:00526000 00001000 IDATA RW MIRC32 .rdata 0004 015F:00527000 00001000 IDATA RO SHARED MIRC32 .INIT 0005 015F:00528000 00002000 IDATA RO MIRC32 .idata 0006 015F:0052A000 00001000 IDATA RW MIRC32 .edata 0007 015F:0052B000 00001000 IDATA RO MIRC32 .reloc 0008 015F:0052C000 00016000 IDATA RO SHARED MIRC32 .rsrc 0009 015F:00542000 0002D000 IDATA RW SHARED

Now if we can see which section the string we searched for was found in, and we can decide if its likely to be the correct match of the search. But what if it wasnt found in the process memory? Just because a string isn't inside the actual process doesnt meen that it can't be accessed by the process, remember that each process have the possibility of accessing 4gb of virtual address space :=) But for a process to use space that isnt part of the actual mapped process it needs to allocate space.

Now, how do we find space allocated by a process? it could be almost anywhere and searching the entire space can be quite futile, and may give a lot of false hits if the string we need is a common one. No need to worry though, softice provides a nice command for these situations:

Command: Heap32
Usage: Heap32 <process>
Output: :heap32 mirc32 Heap: 00570000 Max Size: 1028K Committed: 20K Segments: 1 Address Size 00570078 00000C7C 00570CF8 00000078 00570D74 0000003C 00570DB4 00000014 00570DCC 00000078 ~~~~~~~~~~~~~~~~~~ lots of entries ~~~~~~~~~~~~~~~~~~ 00670FBC 0000000C 00670FCC 0000001C 00670FEC 00000010 Used: 16K Free: 1011K

Now this will produce quite long list on some applications, but dont worry too much about that, look at the first entry 00570078 and the last one 00670fec. This tells us that mIRC32 is using space that is outside of the process, allocated space :) now all we have to do in case we dont find our string in our process space, is to search the allocated space, the easiest way is just to put first entry in the list as start address and the length to the difference between them.

If you actually look at the entrie you will notice a pattern, some of them are at 0057xxxx and the others are at 0067xxxx, you might also have this divided kind of thing, it simply means that the memory was allocated as 2 main chunks, the first one starts at 00570000 and the second starts at 00670000. We won't go into memory allocation any further at this point, maybe another day. now lets continue

Make sure you switch to the mIRC32 context, (use the proc and addr commands) and then type d 570000 (you should of course use the address you find in your own heap32 list of mirc32). You can now view what mIRC32 keeps in its allocated space. This space can be searched just like the process memory and of course you can put breakpoints on when the allocated memory space is read from or written to.

Oh well, thats all from me now, I hope you find some use for this, I know I wouldn't wanna live without theese commands, and even if some of you may think of them as a waste of time, I can promise that there are times when they make life a lot easier (and apart from that you may actually wind up learning a bit about how programs actually look in memory and what they can and can not do)

Well, off you go then... good luck, and have a nice day

NoodleSpa

Article hosted by f0dder(a)flork.dk (f0dder.has.it), last edit at 2001-07-19.