Patching CD-Checks | |||
Intro | |||
TOOLS USED : WDASM, hex-editor |
|||
Where to start? | |||
LPCTSTR lpRootPathName // address of root path Value Meaning 0 The drive type cannot be determined. 1 The root directory does not exist. 2 DRIVE_REMOVABLE The drive can be removed from the drive. 3 DRIVE_FIXED The disk cannot be removed from the drive. 4 DRIVE_REMOTE The drive is a remote (network) drive. 5 DRIVE_CDROM The drive is a CD-ROM drive. 6 DRIVE_RAMDISK The drive is a RAM disk. So, the API checks what type of drive LPCTSTR points to. For a CD-ROM
the return value will be 5. Now we are ready to check the deadlisting :) |
|||
The code | |||
* Possible StringData Ref from Data Obj ->"A:\" * Reference To: KERNEL32.GetDriveTypeA, Ord:00F0h 00401011 E800010000 Call 00401116 00401016 83F805 cmp eax, 00000005 ; Check if drive is CD-ROM 00401019 7411 je 0040102C ; If it is, jump to 'check CD' 0040101B 803D363040005A cmp byte ptr [00403036], 5A ;check if drive = 'Z' 00401022 7440 je 00401064 ; If it is, jump to 'CD not found' * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: 00401062(U), :004010B0(U), :004010E0(U) 00401024 FE0536304000 inc byte ptr [00403036] ; Increment first byte of ; the string with root path ; so it points to the next drive 0040102A EBE0 jmp 0040100C ; Jump back to check next drive What happens in the above code? We start to check if 'a:\' is a CD-ROM.
If it is no CD-rom, we increment the first byte of the root path-string.
* Referenced by a (U)nconditional or (C)onditional Jump at Address: 00401019(C) * Possible StringData Ref from Data Obj ->"A:\" 0040103D 6836304000 push 00403036 ; Push pointer to root path * Reference To: KERNEL32.GetVolumeInformationA, Ord:0162h 00401042 E8DB000000 Call 00401122 ; Get the Volume Name of the drive 00401047 51 push ecx 00401048 33C9 xor ecx, ecx ; Make ecx zero * Referenced by a (U)nconditional or (C)onditional Jump at Address: 00401060(U) 0040104A 8A8100304000 mov al, byte ptr [ecx+00403000] ; Move byte of 'THE MATRIX' to eax 00401050 3881AA314000 cmp byte ptr [ecx+004031AA], al ; Cmp volumename with 'THE MATRIX' 00401056 750A jne 00401062 ; If a byte is different, we jump to 'check next drive' 00401058 41 inc ecx ; Add 1 to counter 00401059 83F90A cmp ecx, 0000000A ; First 10 bytes equal? 0040105C 7202 jb 00401060 ; If not 10 bytes yet, go check next byte 0040105E EB1E jmp 0040107E ; jump to 'Next CD check' The above code is quite simple, the program fetches the VolumeName of the CD-ROM drive, and checks it with a string. To know the contents of the string at address 00403000, press the 'data hex' button in Wdasm (you will see that it is 'THE MATRIX'). If the VolumeName is 'THE MATRIX' we jump to the next CD check, otherwise we jump to 'Check next drive'. * Possible StringData Ref from Data Obj ->"A:\" 0040107E 6836304000 push 00403036 00401083 68C2314000 push 004031C2 * Reference To: KERNEL32.lstrcpyA, Ord:02DCh 00401088 E8A1000000 Call 0040112E ; Copy root path in new string * Possible StringData Ref from Data Obj ->"Matrix.DVDivX.*" 0040108D 684A304000 push 0040304A 00401092 68C2314000 push 004031C2 * Reference To: KERNEL32.lstrcatA, Ord:02D3h 00401097 E88C000000 Call 00401128 ; Paste 'MatrixDvDivx.*' behind the root path 0040109C 6860304000 push 00403060 ; Poiter to a WIN32_FIND_DATA structure 004010A1 68C2314000 push 004031C2 ; Pointer to the string just created * Reference To: KERNEL32.FindFirstFileA, Ord:008Ch 004010A6 E865000000 Call 00401110 004010AB 83F8FF cmp eax, FFFFFFFF ; Is the file there? 004010AE 7505 jne 004010B5 ; then jump to 'Next check' 004010B0 E96FFFFFFF jmp 00401024 ; else jump to 'Check next drive' * Referenced by a (U)nconditional or (C)onditional Jump at Address: 004010AE(C) :004010B5 A3BE314000 mov dword ptr [004031BE], eax ; Store File Handle * Reference To: KERNEL32.FindClose, Ord:0088h 004010C0 E83B000000 Call 00401100 ; Close the searchHandle 004010C5 A180304000 mov eax, dword ptr [00403080] ; Move size member of WIN32_FIND_DAT to eax 004010CA 3B055A304000 cmp eax, dword ptr [0040305A] ; Check size with dword 004010D0 7504 jne 004010D6 ; If not equal, jump to 'Check next Drive' 004010D2 EB07 jmp 004010DB ; Else, jump to good-guy message 004010D4 EB05 jmp 004010DB * Referenced by a (U)nconditional or (C)onditional Jump at Address: 004010D0(C) 004010D6 E949FFFFFF jmp 00401024 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: 004010D2(U), :004010D4(U) 004010DB 6A00 push 00000000 ;Good guy Message * Possible StringData Ref from Data Obj ->"Great!" 004010DD 6843304000 push 00403043 * Possible StringData Ref from Data Obj ->"CD Found" 004010E2 683A304000 push 0040303A 004010E7 6A00 push 00000000 * Reference To: USER32.MessageBoxA, Ord:01BBh 004010E9 E806000000 Call 004010F4 004010EE 50 push eax * Reference To: KERNEL32.ExitProcess, Ord:0075h 004010EF E806000000 Call 004010FA ; Exit ProgramIn the above code, the following happens : First the root path and a file string get pasted together. (eg. 'F:\' + 'Matrix.DVDivX.*' = 'F:\Matrix.DVDivX.*') Then the program checks if a file which matches the description is there. If not, we jump back to 'check next drive'. If it is there, the program checks its FileSize with the value in 0040305A. (If you press the dataHex button again, you can see that value : 2B6F2000h (mind the reversed order) = 728.702.976 bytes ) If the FileSize matches this value, the program assumes that the right CD is inserted. If not, we go to 'check next drive' again. |
|||
Patching the code | |||
I assume that your computer has a CD-ROM drive. When the program finds your CD-ROM drive, it will check the VolumeLabel. To prevent from jumping back to 'check next drive' we nop that jump out : 00401056 750A jne 00401062 -> nop nop 750A -> 9090 Next, the program searches for the file, let's change the conditional jump so it always jumps to the next check : 004010AE 7505 jne 004010B5 -> jmp 004010B5 7505 -> EB05
004010D0 7504 jne 004010D6 -> nop nop 7504 -> 9090Get all the FileOffsets of the above codelines in Wdasm (displayed at the bottom of the screen in hex), fire up your hexeditor and change the appropriate bytes. Run the program, now it thinks the CD is inserted ! Job done :) The method to check the CD I used in my little matrix-proggy is very simular to how it's done in real programs. Of course, don't expected that the program you want to patch, will only check one file, or will have such clean code as my proggy :)) Good luck!
If you have questions, or remarks abou this tutorial, feel free to mail me.
Detten |
|||
|