Log in

View Full Version : Need help before i go nuts!


Snoop
November 15th, 2002, 01:33
Hi all,
I am doing a crackme that i had to do a couple of work on it to do my homework!. Everything i had to do is done. I understand how the serial is generated with the name and every thing. Since i am more than a newbie even if the work on this crackme is finish i wanted to go further and learn more. So i decide to do a keygen for the crackme. Nothing to write my mom about, but still, for a newbie it's just ok. I am using radASM and the keygen is in MASM. I could read asm good, but to write it and code with it it's another thing. It's not my programming language as i work with a 4gl in life. Ok nof said.

What i did is only took the code block that generate the serial in the dead listing (am using ollydbg) and took it to generate in the keygen. Brefly, the only thing to do is recreate the same thing that the proggie does... But when i click on the generate button i have a window error message telling me that the application is using blabla part of the memory and that this cannot be "read"...
In other word, it stop! I suppose that in my routine i probably use a register that am not suppose to.. anyway. Could somebody point me out as i am really confuse
Here is the code for those who could see the problem write away and below i will include the src with the exe. Waiting a reply i will continue and try to figure out what is the problem.
Am on win2k, this prog is writting with RadASM v1.1.2.7, and link and build with MASM v5.
Keep in mind that i am a real newbie in asm programming so please dont come up with some complex explanation.
Snoop

Keygen proc
xor edx, edx
xor eax, eax
xor ebx, ebx
mov edi, offset buffer2 ; EDI will have the serial generated
mov esi, offset buffer ; ESI hold the name entered
mov ecx,10
JMP1:
MOVSX EAX,BYTE PTR DS:[ESI+EBX] ; Pickup character
test al, al ; Verify if finish
jz JMP2 ; If finish then get see u!
CDQ
IDIV ECX
XOR EDX,EBX
ADD EDX,2
CMP DL,10
JGE jmpsub
MOV BYTE PTR DS:[EDI+EBX],DL
INC EBX
JMP JMP1

jmpsub:
SUB DL,10

JMP2:
xor edx, edx
xor eax, eax
xor ebx, ebx
ret
Keygen endp
end start

** this is a refresh version

Kayaker
November 15th, 2002, 05:13
Hi

Works for me on Win98SE. I don't see anything overtly wrong with your code or the compiled PE. You could try upgrading to MASMv7 or use the .386 directive instead of the .586 one with MASMv5. Have you verified the DS: qualifier in your mov statements doesn't point to an invalid data segment with Win2K for some reason? Try removing them (they're not really necessary) and see what happens. Debugging with Softice should lead you to the invalid call I would think.

Kayaker

Snoop
November 15th, 2002, 06:24
hi Kayaker, i have removed the ds statement, nothing change.
I tried after, instead of picking up each character of the name entered with MOVSX EAX,BYTE PTR DS:[ESI+EBX] statement to
LODSB and instead of saving with MOV BYTE PTR DS:[EDI+EBX],DL
i put STOSB, in a way or another they all point to the same register(that's what i've read...) and i still have the same error message...
Thank's for your advise anyway. I will keep on looking up, try to change couple of things a see how it goes..
Keep you inform of that.

Snoop

Kayaker
November 15th, 2002, 08:35
What's the exact error message? Like, what's the blabla in "blabla part of the memory"?

Snoop
November 15th, 2002, 08:59
Well.. i am trying to upload a snapshot but dont seem to find how to do so..
anyway its a windows error message saying...

Instruction "0x77e0fa1c" is is using memory segment
"0x0000002b". The memory could not be "read"

Click ok to terminate the program.
Click Cancel to debug the programe.

Note that this is translate as i work with win2k (french) but it exaclty what it mean's..

Like i said, at one point in the program i guess that am using a bad register to do a certain instruction. It compile but go crazy when running.
--> Kayaker, you say that it's running on win98se? If you put a name and click on the generate does it actually generate you something?

Snoop

Snoop
November 15th, 2002, 10:14
Ok, i have some development here as my wife and kids are about to get up for a new day, and me the crazy i did a trip round the clock

at the begining of the keygen procedure i do a xor ebx,ebx (to put it at zero) and a bit further i am using this ebx to do a xor and increment it for my loop.

well this is the problem, if i remove the xor ebx,ebx at the begining there is no problem but the result is not good. When i have the xor ebx,ebx at the begining i have the error msg when running.. humm So i tried to initialize it with a mov edx,0 instead.. nop! wrong answer. So i really have a problem with this logic. I found the problem debuging with ollydgb(tried sice but for now find this one more convivial for newbie).

So there i am. Stick with some register... and still dont know how to correct it..

Snoop

neviens
November 15th, 2002, 11:06
Try to save used registers @ begin of proc and restore
at end:

push ebx
push ecx
.
.
.
pop ecx
pop ebx

Neviens.

PS Your source compiles different and don't work on
my w98se, but precompiled .exe works well.

ZaiRoN
November 15th, 2002, 11:07
Hi Snoop.

first of all, I have seen the image; the link http://www.quebecweb.ca/errormsg.jpg is right, where's the problem?

I have win98se too and I have tried your keygen, no crash for me. I don't know why your proggie crash
Anyway:
Quote:
If you put a name and click on the generate does it actually generate you something?
I inserted a name and the keygen generated this sequence of bytes: 02h 08h 09h 03h 07h
Strange serial, I bet the right serial is 289375 (02h+30h, 08h+30h, ...).

I read you have ripped the code from the original crackme; this might be the problem. Are you sure you have not missed something?
Here is a little thought (I could be wrong) about the keygen which might help you:
Code:
CMP DL,10 <-- the serial is filled with numbers (0..9)
JGE jmpsub
MOV BYTE PTR DS:[EDI+EBX],DL
INC EBX
JMP JMP1

jmpsub: <-- you will arrive here if DL is not in 0..9 range
SUB DL,10 (*) <-- after that: 0 =< DL < 10 so it might be a new serial char

JMP2:
xor edx, edx <-- edx = 0
(*) which is the sense of this? Maybe after that there is a jmp instruction to 'MOV BYTE PTR DS:[EDI+EBX],DL'

my 2 cents...

regards,
ZaiRoN

Snoop
November 15th, 2002, 11:58
--> neviens, i will try that. Thanks.

--> ZaiRoN, here is the gen from the crackme

1 - 401632 |> 0FBE041E /MOVSX EAX,BYTE PTR DS:[ESI+EBX]
2 - 401636 |. 99 |CDQ
3 - 401637 |. F7F9 |IDIV ECX
4 - 401639 |. 33D3 |XOR EDX,EBX
5 - 40163B |. 83C2 02 |ADD EDX,2
6 - 40163E |. 80FA 0A |CMP DL,0A
7 - 401641 |. 7C 03 |JL SHORT 401646
8 - 401643 |. 80EA 0A |SUB DL,0A
9 - 401646 |> 88141F |MOV BYTE PTR DS:[EDI+EBX],DL
10- 401649 |. 43 |INC EBX
11- 40164A |. 3B1D 63344> |CMP EBX,DWORD PTR DS:[403463]
12- 401650 |.^75 E0 \JNZ SHORT 401632

Ok, my understanding of this is that...
(refer to number at left)
eax hold the name
ecx = 10
PTR DS:[403463] hold the lenght of the name entered


1- move in eax 1 character from the name, wich would be the
character at the position that ebx have, ex ; Name = Snoop and
ebx = 0, then we pick up "S" and so on...

2- Converts the signed dword in EAX to a signed quad word in
edx:eax

3- Signed integer division, in this case the src value is a word so
dx:ax is divided by ecx (wich is 10), the quotient is stored in AL and the remainder in dx.

4- perfome an exclusif or
5- Add 2 to edx
6- Compare DL with 10
7- If dl is less to 10 then jump the next line
8- if dl is equal or greater to 10 then substract 10 to dl
9-Store the first number of the valid serial
10- inc ebx for the loop purpose
11- Compare ebx with the length of the name user have input
12- if not zero then perform the hole thing again.

Ok, now there 2 other loop after this, one who perform calculation of the serial that the user as entered and the other one is the validation. But the one important is the one describe.
So now my problem is not really the understanding it's more the programming in asm!
So what i thought was simply that the same peace of code and badabim badabang i would have a nice little kengen. But it look's like the asm program do not like what am doing with EBX register, as i mention before in previous reply. I really dont know why.. here is my new procedure as i work on it and change it. Now this is working(well...way of speeking) but the serial that it generate's me is this square character , if i enter Snoop i will have 5 square character as serial...

Keygen proc
xor edx, edx
xor eax, eax
;if i do a xor ebx,ebx or mov ebx,0 here it will crash at run time.
mov edi, offset buffer2
mov esi, offset buffer
mov ecx, 10

JMP1:
LODSB
test al, al
JZ JMP6
CDQ
IDIV ecx
XOR EDX,EBX
ADD DL,4
CMP DL,10
JGE JMPSUBIT
MOV AL,DL
STOSB
INC EBX
JMP JMP1

JMPSUBIT:
SUB DL,10
STOSB
INC EBX
JMP JMP1

JMP6:
ret
Keygen endp

I think i know why, this is because before entering in the loop, EBX is not at zero, it hold some kind of value from i dont know where, and i cant perform a xor ebx,ebx or a mov ebx,0 just before entering in the loop because then it will crash at execution.
So i hope i was clear... maybe a bit to much!!!
Thanks

Snoop

ZaiRoN
November 15th, 2002, 13:01
Maybe I misunderstood you, sorry

Please, correct me if I'm wrong (I need to understand). You have fundamentally two problems:
1. Find the reason why the proggie crash
2. Find the right serial (and not 5_square_character)

1.
Your keygen crash when ebx=0; this sounds strange. Have you tried to step (line after line) the keygen with Olly ? Which is -exactly- the instruction that cause the crash? The 'xor ebx, ebx'?

2.
Quote:
Ok, now there 2 other loop after this, one who perform calculation of the serial that the user as entered and the other one is the validation. But the one important is the one describe.
- the crackme takes the name and performs a calculation on it obtaining n1
- the crackme takes the serial and performs a calculation on it obtaining n2
- if n1=n2 then you are registered, otherwise not registered
Does the program work in this way?

Quote:
I think i know why, this is because before entering in the loop, EBX is not at zero
Hmmm... are you sure? Either if ebx=0 the serial will be *5_square_character*...

ZaiRoN

Manko
November 15th, 2002, 13:23
You have to format your key for output, else it won't display...
The code snippet you have was never meant to SHOW the key...

As for the crash... dunno. Maybe you can't send it such a "faulty" string?
(I know Jack-shit about programing, though...)

/Manko

Snoop
November 15th, 2002, 17:23
ZaiRoN
Quote:
Please, correct me if I'm wrong (I need to understand). You have fundamentally two problems:
1. Find the reason why the proggie crash
2. Find the right serial (and not 5_square_character)

1. Find the reason why my keygen is crashing
2. yes

Quote:

the crackme takes the name and performs a calculation on Does the program work in this way?

Yes, exaclty like that.
This is the second loop of the crackme (Take the serial that the user have input)
MOVSX EAX,BYTE PTR DS:[ESI+EBX]
99 |CDQ
F7F9 |IDIV ECX
MOV BYTE PTR DS:[EDI+EBX],DL
43 |INC EBX
3B1D 63344> |CMP EBX,DWORD PTR DS:[403463]
JNZ SHORT 401632

It does the same thing except the xor, adding 2 and sub 10 if greater.

And the final loop only compare the result of first loop with result of second loop.

So for my key gen i only have to take the same code as the first loop but except adding 2, i have to add 4 to dl before storing because in the second loop of the crackme(the calculation made by the serial entered) there is not the addition.

Ex, name Snoop
valid serial 75760
if i enter this it will go to good boy
what it did
The first loop, after generating the valid serial for Snoop in edi i have a result of 53548
The second loop, after taking the serial that i have entered(who was 75760) and perfoming the calculation will have have 53548
Third loop compare both and jmp either bad or good boy.
Me, in my key gen, i take the name entered, perform the same calculation as the first loop but instead of adding 2 i add 4 in order to get a valid serial number.

Maybe Manko is right here
Quote:

You have to format your key for output, else it won't display

seem's very logic and this would explan why i get some square's, but how??

Quote:

As for the crash... dunno. Maybe you can't send it such a "faulty" string


When i am adding xor ebx, ebx before the loop and i trace the keygen i remark that it actually generate the valid serial number (and dont crash at this point) it crash when calling the SetDlgItemTextA (when the good serial generate from the keygen is being display in the grey edit box of the keygen) it's like if doing the xor ebx,ebx change the type.. i dont know...

Is there a way that i could take a variable instead of ebx? Because bottom line the only reason why i need ebx is to perform a xor and increment it for the loop, so it act as a counter.

Many apologies to all if this is not very clear.. im trying to explan the best i could. I dont want to sent the crackme as it is part of the REA web site that Kayaker point me to be a good place to learn (And it really is). So this is like my first homework, so i dont want to sound like somebody who is trying to have other's to do it for him. Like i said in the very beginning I did all that was to be done an understand everything that as to be understand for this crackme, i could of just right away submit my thing's and would be upgrade to the next crackme level. It's only that i would like to submit this keygen i am working on. I dont have to submit real keygen in order to go to the next level, only write what i would do to recreate a good serial. So this i know exaclty what to do
to keygen it.

This keygen is beyond the thing i had to do... only for me. But my problem lies on the programming language. I would be able to do this little generation in 2 minute with a 4 gl language... but it's been doing 2 ... days!!!! With this assembly thing. I am the kind that dont givup easely but i am starting to think about it....
Thank's

BTW, I have upload a refresh of my keygen so if you would like to download it as the other is out of date.

Snoop

ZaiRoN
November 15th, 2002, 18:03
Hi Snoop.
Quote:
Me, in my key gen, i take the name entered, perform the same calculation as the first loop but instead of adding 2 i add 4 in order to get a valid serial number.
Your analysis is not properly correct. You need to do something else to solve the problem. Sorry but I can't say anymore (Zero might kill me )

Quote:
When i am adding xor ebx, ebx before the loop and i trace the keygen i remark that it actually generate the valid serial number (and dont crash at this point) it crash when calling the SetDlgItemTextA (when the good serial generate from the keygen is being display in the grey edit box of the keygen) it's like if doing the xor ebx,ebx change the type.. i dont know...
So, 'xor ebx,ebx' might not be the problem; try to change manually the value pointed by edi before SetDlgItemTextA (put something like: 0x30 0x31 0x32) and to see if the keygen crash again. If the crash doesn't happen then the problem resides in the serial otherwise...don't know.

Don't discourage yourself and good luck!
ZaiRoN

Kayaker
November 15th, 2002, 18:05
Ahhh, EBX. You MUST preserve ebx, edi, esi if you use them in any procedure. Push/pop them as neviens said or uses the USES directive.

I should have seen this with my eyes closed because JimmyClif reminded me about my sloppy use of the ebx register in my Snippet Creator thread code just the other day, lol. (of course in a real patch you always use pushad/popad and maybe pushfd/popfd to protect your ass

Preserving ebx is apparently less critical in Win98, where you can get away with it, than it is in Win2K and above. You could probably trace into the Kernel code after returning from the wm_command proc and find where original value of ebx is being used.

Go to the Win32ASM messageboard and do a search for 'register preservation' or similar and you'll find several discussions about the issue, and why ebx is probably the culprit in this case.

http://board.win32asmcommunity.net/search.php?

Kayaker

Snoop
November 15th, 2002, 18:19
Kayaker
Quote:
You could probably trace into the Kernel code after returning from the wm_command proc and find where original value of ebx is being used

I effectivly did it.. like you say it is not at the program point but in the kernel.. and this is being beyond my knowlede to follow this for now I will try to push/pop and go read a bit on WIN32Asm board. Thanks for the info

ZaiRoN
Quote:
Your analysis is not properly correct. You need to do something else to solve the problem

Well.. i was thinking getting it right... I will try to see what you mean. But when i do it manually (calculation) on a paper it always return the good value... strange.. anyway I will find out what is missing.

Quote:
change manually the value pointed by edi before SetDlgItemTextA (put something like: 0x30 0x31 0x32) and to see if the keygen crash again

Yes i will try this, did not think about that.

BTW, cant beleave how fast are coming the reply's here! Very nice board with very pleasant poeple to help us out.
Thank's a bunch to you guy's/gual's for your support.
I am going to sleep a bit as i am starting to see my computer screen moving from left to right without even touch it... (i think this is not a good sign !!) i will get back on this after and keep you inform
Thank's again

ZaiRoN
November 15th, 2002, 18:28
This explains why sometimes my asm programs crash on w2k system.

ZaiRoN

Manko
November 15th, 2002, 19:15
Quote:
Originally posted by Snoop


quote:
--------------------------------------------------------------------------------

You have to format your key for output, else it won't display
--------------------------------------------------------------------------------

Maybe Manko is right here

seem's very logic and this would explan why i get some square's, but how??

Snoop

Just add 30 to each byte and you have the ascii for the corresponding number...
Zairon mentioned it earlier in the thread, sorta...

/Manko

Snoop
November 15th, 2002, 21:59
Quote:
Just add 30 to each byte and you have the ascii for the corresponding number...


flow of generation;
pickup let's say character "s" from the name field

HEX = 73
DEC = 115

divide 115 by 10, put reminder in DL, (whitch is interesting me)

DL = 5
Add 2 to DL
DL = 7
Store DL
repeat for next caracter.
(Me in my key gen i would add and additional 2 to DL as in the serial validation of the crackme there is no add 2 to DL)

So in the crackme name field if i enter s in the name and 9 in the serial field and validate this jump to good boy.

so let's say that after the gen loop from the name example (abcd) in the crackme the valid serial is 2560 ( **those are not the correct value but only for purpose of example) then me in my key gen i would have to output 4782 to the user as a valid serial key. So in the crakme if i enter abcd in the name and 4782 in the serial this will go to good boy.

Let's say example after the valid gen in the crackme the value is 8 then me in my keygen i would have to output 0 because its 8 + 2 wich is 10 but if 10 or greater i substract 10 to the value...


Quote:

Quote from ZaiRoN
Your analysis is not properly correct. You need to do something else to solve the problem

That's why i dont really know where i am missing something here... because the way i do it it always generate a valid key for the name entered... but i will continue to look closely to see where i am missing something.

See u all
Snoop


Follow up

Ok forget about what i said in this reply... I've decided that tonight once for all i would kick the s**t out o that! I've turn'ed on some Marley in my speaker's, twist a cap of Guiness (well... more than one!) light up a biggie sp.. heee cigarette of course, sit back comfortably, read this post from the begining, and I was ready to roll


ZaiRoN, i guess i know what i am missing. I'll check a thing or two and come back on you for this one.

neviens and kayaker, yes, push and pop actually did correct the problem. Thank's. I read a bit more about it on the w32asm board.

Manko, i will format it and let you know. I just realize that i have a hard time to switch between ascii ->hex->decimal and decimal->hex->ascii.
So that's it.. anyway. It maybe very stupid to do for some but for me i am learning alot and i like it.
G'night
Snoop

Snoop
November 17th, 2002, 06:40
Well, thanks for clearing me some points everybody. Yesterday, like said in the previous reply, i've decided to go for it.
I know understand and i learned alot from this crackme as it was my first one and my first keygen to..

Greeting's all
Snoop