Log in

View Full Version : distinguishing between imul and mul in C


tdennist
November 4th, 2004, 17:36
I've been working on a crackme for about 3 days now. I've got everything I need completed, I think, and the keygen is made. The one problem: the keygen doesn't produce the right number ;-). No, I'm not asking for someone to tell me what's wrong with the keygen. I think I know the problem.

In this crackme, this line exists:

Code:
IMUL EAX,6


EAX at this point contains the last letter of the name I entered. What I have in my keygen C file is:

Code:
foovar *= 6;


(Yes, foovar is a char containing the last letter ). My question is: are these two lines equivalent? If they aren't, can you tell me how I can make them equivalent? And if they are...I guess I have some more work to do ;-).

Thanks.

(as a side question, is it possible to edit code in IDA? I was frustrated and was going to change the TEST EAX,EAX before the jnz instruction to XOR so that I could feel good about entering a correct serial, but I couldn't figure out how to edit code in IDA. Thanks again.)

dELTA
November 4th, 2004, 18:57
Try to use inline assembler for that line, and see if it helps.

And about patching in IDA:
http://www.woodmann.com/forum/showthread.php?t=3670

tdennist
November 4th, 2004, 19:47
I've never tried inline assembly before, so a bit of googling turned up a solution. But...the solution doesn't work. Here's my code (with line numbers):

Code:

41: foovar = name[4];
42: ++count;
43: foovar = (foovar^count);
44: ebx += foovar;
45: cout << ebx << endl;
46:
47: //foovar *= 6;
48: __asm
49: {
50: mov eax, foovar
51: imul eax,6
52: push eax
53: call printf
54: pop ebx
55: }
56:
57: ebx <<= 7;
58:
59: eax = (foovar + ebx);
//etc. more code follows.


I'm compiling it in Cygwin, and g++ gives me these error messages, along with errors on all the rest of the lines in the file:

Code:

keygen1.cpp: In function `int main()':
keygen1.cpp:49: error: parse error before `{' token
keygen1.cpp: At global scope:
keygen1.cpp:57: error: syntax error before `<<=' token
keygen1.cpp:59: error: ISO C++ forbids declaration of `eax' with no type
keygen1.cpp:59: error: `foovar' was not declared in this scope


Any ideas?

disavowed
November 5th, 2004, 02:22
you're trying to use msvc++'s inline asm syntax with the g++ compiler. the g++ inline asm syntax is here: http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html ("http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html")

naides
November 5th, 2004, 08:07
Sorry for dropping in: imul does a signed multipication. foovar is the ascii code of a letter which should be a small, unsigned char. The two operations imul and *= should be equivalent with small ascii codes, below ox7F.



I suggest you trace both the crackme and the keygen (you have the luxury of compiling it with debug info and see the code in proper debugger fashion) and see if the results are the same. My gut feeling is that the problem is somewhere else.

Note: after looking at the code you posted later, foovar contains a computed number which is not simply the ascii code of a letter, then, signed multiplication, overflow and roleover make a lot of difference, numbers above dec 127 or ox7F are interpreted as negative, so imul and *= are not equivalent operations.

doug
November 5th, 2004, 23:41
besides, using register names as variable names is probably a bad thing if you intend to inline code.
gcc's AT&T asm syntax probably avoids messing things up with the % prefix.. but it took me a while to figure out which identifiers are variables and which ones are registers.

BTW, what is that printf call on line 53? no parameters?

to add to what naides said: right shifts are also common mistakes when converting asm to C or C to asm. (i.e.: what happens with the sign bit varies)

Madmartigan
November 6th, 2004, 05:22
If you put the char in foovar into an int (a signed int, and the compiler will assume you mean a signed int as long as you don't write unsigned before it), the compiler will generate an imul instruction with a 32-bit operand, which is exactly what is done in the crackme.

tdennist
November 7th, 2004, 19:06
Doug:
Yeah, I guess that is a not so hot idea. I just don't really like variable names like "temp" and such (though..."eax" and "ebx" are hardly any better ). That printf call on line 53 is in the crackme.... I shouldn't have included that, and I don't know why. The original code in the crackme is this:
Code:
push offset aLx ; format
lea ecx, [ebp+buffer]
push ecx ; buffer
call _sprintf

So as you can see, I typoed it as well as didn't include the other parameters 8-). I think I might have had a reason for it when I wrote it, but that was like a week ago, so I don't know.

Madmartigan: I'm afraid I've been programming too much in Perl/ASM lately...how would I go about moving the value from foovar into an int? Is it simply:

Code:
int temp; // yes, I do hate these names
temp = foovar;



Thanks for your replies.

Madmartigan
November 8th, 2004, 05:28
Yes, exactly.