WDASM 8.0 ANOTHER APPROACH
(API-call crackig galore)
by Wuzat
(with a correction to the "font" problem) by +Jed
Courtesy of Fravia's page of reverse engineering
~
Wuzat's esssay is VERY interesting: the API-call relocation trick is clever, useful
and well explained using as example wdasm32 version 8, a program that you'll find everywhere
(and a most useful program as well as you all already know), enjoy!
~
+Jed (probably the more
"+orcish" of all +crackers :-), corrects the "fonts" problem that many of you have
experienced with recent copies of wdasm8! 12 May 1997__NEW!__
WDASM 8.0 ANOTHER APPROACH BY WuZat
(API-call crackig galore)
Wow ! Kovi made it faster than me !!
So THIS will only be an add-on to his cracking of wdasm80 and does not include
the Counter-crack. This is my own contribution to our common "quest".
The problem: I cant even imagine to search w32dsm00?.tmp inside c:\windows\tmp
every craking session. (maybe I'm too lazy ?)
The solution (well in fact two solutions): at first, I imagined to get the file
inside my w32dsm8 directory (and I found a solution for this as well), but finally,
I found it more convenient to get it inside the target file's directory (kind of
a multi-cracking environnement). I did'nt remove the first cracking solution from
this file, even if the second one is more convenient, because I think it could
represent a nice trick that you could eventually use in another context.
OK, now, let's zen-crack a bit ;-)
Searching for API calls to Createfile(), whe find some locations... only one is
preceded by "\w32dsm%02d.tmp" (in fact we could have directly searched this very
string !)
Heres the incrimined (commented) code section
:00464E9D 8D95D8FEFFFF lea edx, [ebp+FFFFFED8]
:00464EA3 52 push edx
:00464EA4 6804010000 push 00000104
* Reference To: KERNEL32.GetTempPathA, Ord:0000h ; First call to get temp path
|
:00464EA9 E810940100 Call 0047E2BE
:00464EAE 8D8DD8FEFFFF lea ecx, [ebp+FFFFFED8] ; destination string
:00464EB4 51 push ecx ; for GetTempPath
:00464EB5 6804010000 push 00000104
* Reference To: KERNEL32.GetTempPathA, Ord:0000h ; Second call to GetTempPath
| ; temp dir now in [ebp+FFFFFED8]
:00464EBA E8FF930100 Call 0047E2BE
:00464EBF 0FBE9405D7FEFFFF movsx byte ptr edx, [ebp + eax - 129]
:00464EC7 83FA5C cmp edx, 0000005C
:00464ECA 7508 jne 00464ED4
:00464ECC C68405D7FEFFFF00 mov byte ptr [ebp + eax - 129], 00
* Referenced by a Jump at Address: |:00464ECA(C)
|
:00464ED4 8BC6 mov eax, esi
:00464ED6 46 inc esi
:00464ED7 50 push eax
* Possible StringData Ref from Data Obj ->"\w32dsm%02d.tmp"
|
:00464ED8 6838584900 push 00495838 ; load file name template
:00464EDD 8D4DDC lea ecx, [ebp-24]
:00464EE0 51 push ecx ; destination string is [ebp-24]
* Reference To: USER32.wsprintfA, Ord:0000h
|
:00464EE1 E83A950100 Call 0047E420 ; "build" file name (now w32dsmXX.tmp)
:00464EE6 83C40C add esp, 0000000C
:00464EE9 8D45DC lea eax, [ebp-24] ; load file name
:00464EEC 50 push eax ; parameter 2
:00464EED 8D95D8FEFFFF lea edx, [ebp+FFFFFED8] ; load tempdir
:00464EF3 52 push edx ; parameter 1
* Reference To: KERNEL32.lstrcatA, Ord:0000h
|
:00464EF4 E8A1930100 Call 0047E29A ; concat tempdir + file name
:00464EF9 8D8DD8FEFFFF lea ecx, [ebp+FFFFFED8] ; result in [ebp+FFFFFED8]
:00464EFF 51 push ecx ; push it
:00464F00 8D83E0504900 lea eax, [ebx+004950E0] ; adress of destination
:00464F06 50 push eax
* Reference To: KERNEL32.lstrcpyA, Ord:0000h
|
:00464F07 E816930100 Call 0047E222 ; Copy tempdirfile in [ebx+004950e0]
:00464F0C 6A00 push 00000000
:00464F0E 6802010000 push 00000102
:00464F13 6A02 push 00000002
:00464F15 8D93604D4900 lea edx, [ebx+00494D60]
:00464F1B 52 push edx
:00464F1C 6A00 push 00000000
:00464F1E 68000000C0 push C0000000
:00464F23 8D8BE0504900 lea ecx, [ebx+004950E0] ; tempdirfile used to create file =20
:00464F29 51 push ecx
* Reference To: KERNEL32.CreateFileA, Ord:0000h
|
:00464F2A E8E7920100 Call 0047E216
:00464F2F 83F8FF cmp eax, FFFFFFFF
:00464F32 750B jne 00464F3F
:00464F34 83FE19 cmp esi, 00000019
:00464F37 0F8660FFFFFF jbe 00464E9D
:00464F3D 33C0 xor eax, eax
APICallCracking, First solution
1 . First Solution (not the one I prefer, but a nice trick though): as everyone could
see, our dear Urbanik uses the GetTempPath() function to fetch the temporary directory.
Here is the function header :
DWORD GetTempPath(
DWORD nBufferLength, // size, in characters, of the buffer
LPTSTR lpBuffer // address of buffer for temp. path
);
this function returns the temporary directory in lpBuffer.
Now, you see, there is another API function that returns the CURRENT directory of the
current process, and uses EXACTLY the same parameters than GetTempPath():
DWORD GetCurrentDirectory(
DWORD nBufferLength, // size, in characters, of directory buffer
LPTSTR lpBuffer // address of buffer for current directory
);
AND THIS FUNCTION IS IN THE IMPORT SECTION OF THE MODULE!!!
All we have to do now is to replace the call to
GetTempPath
by a call to
GetCurrentDirectory
and here is the "trick": calls are RELATIVES as we can see above: we have there
two subsequent calls to GetTempPath, with different values:
LineA :00464EA9 E810940100 Call 0047E2BE // First Call
^^^^^^^^------00019410 is the RELATIVE Adress (name it CallA)
LineB :00464EBA E8FF930100 Call 0047E2BE // Second Call
^^^^^^^^------000193FF is the RELATIVE Adress (name it CallB)
now, look closely!: 00464eba(LineB) - 00464ea9(LineA) = 11 (hexa)
00019410(CallA) - 000193FF(CallB) = 11 (hexa)
Therefore, we CAN deduct the relative adress we should use in order to call from
ANOTHER call, the one we choose to use in order to call-crack this protection scheme:
let's search somewhere in the dead listing a call to GetCurrentDirectory().
We Find it at 00465070, here it is:
* Reference To: KERNEL32.GetCurrentDirectoryA, Ord:0000h
|
:00465070 E819920100 Call 0047E28E
LineC = 465070
CallC = 00019219
Well, you already understand, don't you... now simply replace the two calls to
GettempPath by two calls to GetCurrentDirectory, deducting the new adress to call:
First call :
LineC-LineA =3D 465070 - 464ea9 = 1C7
NewCallA - CallC = 1C7 > NewCallA = CallC + 1C7 = 00019219 + 1C7 = 193e0
And therefore, here is the newlineA : E8E0930100
Second Call :
LineC-LineB = 465070 - 464eba = 1B6
NewCallB = CallC + 1B6 = 193CF
And therefore, here is the newlineB : E8CF930100
Finally this is the patch for the Solution 1
////////////////////////////////////////////
search 8D95D8FEFFFF5268040100006804010000E810940100 (or less ! :)
replace by E8E0930100
search 8D8DD8FEFFFF5168040100006804010000E8FF930100
replace by E8CF930100
////////////////////////////////////////////
2 . Second Solution, new crack approach (Far Better IMHO)
This time, the idea is to Remove the directory information, thus enforcing
wdasm to create the file in the TARGET directory :
We simply exchange the adress of the string passed to CreateFile (wich
actually is what I called "tempdirfile") with the "nude" file name at [ebp-24],
and use "la bonne vieille technique" of +ORC to fill the three spaces
unused
:00464F23 8D8BE0504900 ****lea ecx, [ebx+004950E0] ; 8D4DDC lea ecx, [ebp-24]
; 904840 NOP, inc ax, dec ax
:00464F29 51 push ecx
and we get the job done!
Besides, there is a side effect in using this method: you do not need anymore to
block the deletion of the file, because the API deletefile uses the file name, not
the Handle returned by CreateFile to delete a file and guess what? For Old good
Urbanik the temporary file is still "tempdirfile" !!
Therefore DeleteFile simply returns 0.
Oups, I almost forgot: to get the job done, replace \w32dsm%02d.tmp (at offset 0x94838)
par w32dasm%02d.txt if you dont want the file to be created in the root of your HD.
And it's safer to let the format parameter.
this is the patch for the Solution 2
/////////////////////////////////////////////////////
// patch provided by WuZat for WDasm8.0 May 1997 //
Search 6A0068000000C08D8BE050490051
Replace by 8D4DDC904840
Search 5C77333264736D
Replace by 7733326431 (or anything that pleases you)
/////////////////////////////////////////////////////
THANKS TO +ORC AND HIS STUDENTS
pour savoir apaiser notre soif de connaissance
(c) Wuzat, May 1997
And here is +Jed's "font problem" correction! Enjoy!
Ok little dudes, this is a small touch by +JED.
Those fonts look jerky ehm? It would be nice to get the clear listing on
the screen. Let's look for "font". We get several TFont constructors,
but only ONE CreateFont! Why the programmer should use the nice and huge
C++ interface of OWL (version 5, by the way... always check what they have
used :-) all the time except for this little direct call to the kernel?
It's saying: come and look at me!
And this is what I'll do:
:00464858 8D830DE30100 lea eax, [ebx+0001E30D]
:0046485E 50 push eax
:0046485F 33D2 xor edx, edx
:00464861 8A930CE30100 mov dl, [ebx+0001E30C]
:00464867 52 push edx
:00464868 33C9 xor ecx, ecx
:0046486A 8A8B0BE30100 mov cl , [ebx+0001E30B]
:00464870 51 push ecx
:00464871 33C0 xor eax, eax
:00464873 8A830AE30100 mov al , [ebx+0001E30A]
:00464879 50 push eax
:0046487A 33D2 xor edx, edx
:0046487C 8A9309E30100 mov dl, [ebx+0001E309]
:00464882 52 push edx
:00464883 33C9 xor ecx, ecx
:00464885 8A8B08E30100 mov cl , [ebx+0001E308]
:0046488B 51 push ecx
:0046488C 33C0 xor eax, eax
:0046488E 8A8307E30100 mov al , [ebx+0001E307]
:00464894 50 push eax
:00464895 33D2 xor edx, edx
:00464897 8A9306E30100 mov dl, [ebx+0001E306]
:0046489D 52 push edx
:0046489E 33C9 xor ecx, ecx
:004648A0 8A8B05E30100 mov cl , [ebx+0001E305]
:004648A6 51 push ecx
:004648A7 FFB301E30100 push dword ptr [ebx+0001E301]
:004648AD FFB3FDE20100 push dword ptr [ebx+0001E2FD]
:004648B3 FFB3F9E20100 push dword ptr [ebx+0001E2F9]
:004648B9 FFB3F5E20100 push dword ptr [ebx+0001E2F5]
:004648BF FFB3F1E20100 push dword ptr [ebx+0001E2F1]
* Reference To: GDI32.CreateFontA, Ord:0000h
|
:004648C5 E8429A0100 Call 0047E30C
And immediately after, we can see:
:004648CA 898355595400 mov [ebx+00545955], eax
:004648D0 8B8355595400 mov eax, [ebx+00545955]
:004648D6 85C0 test eax, eax
:004648D8 7433 je 0046490D
:004648DA FFB355595400 push dword ptr [ebx+00545955]
:004648E0 FFB359595400 push dword ptr [ebx+00545959]
* Reference To: GDI32.SelectObject, Ord:0000h
|
:004648E6 E8699A0100 Call 0047E354
:004648EB 89830BA54500 mov [ebx+0045A50B], eax
:004648F1 8B930BA54500 mov edx, [ebx+0045A50B]
:004648F7 85D2 test edx, edx
:004648F9 740B je 00464906
:004648FB 8B8B0BA54500 mov ecx, [ebx+0045A50B]
:00464901 83F9FF cmp ecx, FFFFFFFF
:00464904 7507 jne 0046490D
* Referenced by a Jump at Address:004648F9(C)
|
:00464906 6AFF push FFFFFFFF
* Reference To: USER32.MessageBeep, Ord:0000h
|
:00464908 E86B9A0100 Call 0047E378
* Referenced by a Jump at Addresses:004648D8(C), :00464904(C)
|
:0046490D 6A00 push 00000000
:0046490F FFB359595400 push dword ptr [ebx+00545959]
* Reference To: GDI32.SetTextColor, Ord:0000h
|
:00464915 E8109A0100 Call 0047E32A
So what, we have a font creation and right after a selection (this is
how windows works). Where's that function called? Two places, let's
see...(you do it)...It seems that every time a KERNEL.UpdateWindow
function is called, this one is called also: CAN YOU FEEL IT? So how to
crack? We could just change the je to jne at 4648d8. This would do it
(try it for yourself). But it's a very ugly crack and the boss would
not like it (I think it's even worse than nopping).
Go back to CreateFont. We'd rather create a GOOD font intead of that
ODD one and then let the program use it. There's a push of the typeface
name. It says "MS LineDraw" (green light). LineDraw is not a nice font
for displaying texts, is it? How bad, we'll change it to a good old
"Courier New". It fits perfectly in it's place...(uhm, I don't feel
comfortable with this crack....) I start the babe again and Gosh! It's
the same old font. Is my "zen" not working? I step back and sip a good
Martini-vodka (remember only Moskovskaya), and meditate...
Let's see the code again:
:00464858 8D830DE30100 lea eax, [ebx+0001E30D]
:0046485E 50 push eax
:0046485F 33D2 xor edx, edx
:00464861 8A930CE30100 mov dl, [ebx+0001E30C]
:00464867 52 push edx
:00464868 33C9 xor ecx, ecx
:0046486A 8A8B0BE30100 mov cl , [ebx+0001E30B]
:00464870 51 push ecx
:00464871 33C0 xor eax, eax
:00464873 8A830AE30100 mov al , [ebx+0001E30A]
:00464879 50 push eax
:0046487A 33D2 xor edx, edx
:0046487C 8A9309E30100 mov dl, [ebx+0001E309]
:00464882 52 push edx
:00464883 33C9 xor ecx, ecx
:00464885 8A8B08E30100 mov cl , [ebx+0001E308]
:0046488B 51 push ecx
:0046488C 33C0 xor eax, eax
:0046488E 8A8307E30100 mov al , [ebx+0001E307]
:00464894 50 push eax
:00464895 33D2 xor edx, edx
:00464897 8A9306E30100 mov dl, [ebx+0001E306]
:0046489D 52 push edx
:0046489E 33C9 xor ecx, ecx
:004648A0 8A8B05E30100 mov cl , [ebx+0001E305]
:004648A6 51 push ecx
:004648A7 FFB301E30100 push dword ptr [ebx+0001E301]
:004648AD FFB3FDE20100 push dword ptr [ebx+0001E2FD]
:004648B3 FFB3F9E20100 push dword ptr [ebx+0001E2F9]
:004648B9 FFB3F5E20100 push dword ptr [ebx+0001E2F5]
:004648BF FFB3F1E20100 push dword ptr [ebx+0001E2F1]
* Reference To: GDI32.CreateFontA, Ord:0000h
|
:004648C5 E8429A0100 Call 0047E30C
No, my feeling is right, but there's something else: What? Let's check
the parameters to CreateFont: It takes an fdwCharSet which is (Godot..)
2!!! This is defined as SYMBOL_FONT. Bingo! Now how would you crack it?
Replace the whole
:00464883 33C9 xor ecx, ecx Zero ecx
:00464885 8A8B08E30100 mov cl , [ebx+0001E308] Get SYMBOL
:0046488B 51 push ecx Push
with some mov ecx, 1 or inc ecx + nops???? Nah! Bad guy. Let's see who
writes 2 at ebx+1e308 and change there....Here:
:0044198B 888307E30100 mov [ebx+0001E307], al
* Possible StringData Ref from Data Obj ->"w32demo7.ini"
|
:00441991 68B5E24800 push 0048E2B5
:00441996 6A02 push 00000002
:00441998 68B2E24800 push 0048E2B2 Data Obj ->"F9"
:0044199D 68A5E24800 push 0048E2A5 Data Obj ->"DEFAULT FONT"
* Reference To: KERNEL32.GetPrivateProfileIntA, Ord:0000h
|
:004419A2 E80FC80300 Call 0047E1B6
:004419A7 888308E30100 mov [ebx+0001E308], al ; HERE!!!
It's the only place where it's written. Hey that push 2 looks ODD. It
seems saying "it's me!" "it's me!". A quick look at the docs (you must
study and know how to get information if you want to crack!) and yep,
that's the default return value if the key is not found. We could either
put a "F9=1" in the w32demo7.ini, under [DEFAULT FONT] or replace the
push 2 with a push 1, which is a much better crack.
That's all folks
+Jed
You are deep inside fravia's page of reverse engineering,
choose your way out:
homepage
links
anonymity
+ORC
students' essays
tools cocktails
search_forms mailFraVia