PDA

View Full Version : Help with What this program does??


gogreen
November 18th, 2013, 05:13
Hello all,

I have this program. 2845, which i need to figure out what it does?

This program takes in two inputs (a,b) from the console and returns another number. At a glance this program seems to output |(a4 - b4)|.

This hypothesis goes wrong when some inputs are given. For example 0 and 5. The program outputs 624 instead of 625. Simlarly for 0 and 10 the output happens to be 9999 as against the expected 10000.

But (5,0) and (10,0) works just fine.

So i opened this program in ollydbg v1.10. Here i found the following things happening with input (0,5):
1) after executing the instruction "00401465 . E8 869B0100 CALL <JMP.&msvcrt.pow>", The ST(0) register was holding "624.99999999999999990", contrary to the expected 625.

2) after executing the instruction "0040147D . DB5D F4 FISTP DWORD PTR SS:[EBP-C]", the value at [EBP - C] was holding " FFFFFD90" (which is -624 in decimal).

Why does the following this happen? Is this something to do with floating point rounding errors?

Kindly help.
Thanks in advance.

Code:
004013C6 . C74424 04 6440>MOV DWORD PTR SS:[ESP+4],Q2.00474064 ; ASCII "Hint: <100"
004013CE . C70424 802F470>MOV DWORD PTR SS:[ESP],Q2.00472F80
004013D5 . E8 BA470600 CALL Q2.00465B94
004013DA . C74424 04 6F40>MOV DWORD PTR SS:[ESP+4],Q2.0047406F
004013E2 . 890424 MOV DWORD PTR SS:[ESP],EAX
004013E5 . E8 AA470600 CALL Q2.00465B94
004013EA > C74424 04 7140>MOV DWORD PTR SS:[ESP+4],Q2.00474071 ; ASCII "Enter 2 integers:
"
004013F2 . C70424 802F470>MOV DWORD PTR SS:[ESP],Q2.00472F80
004013F9 . E8 96470600 CALL Q2.00465B94
004013FE . 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10]
00401401 . 890424 MOV DWORD PTR SS:[ESP],EAX
00401404 . B9 A02D4700 MOV ECX,Q2.00472DA0
00401409 . E8 BEF20300 CALL Q2.004406CC ; first argument
0040140E . 83EC 04 SUB ESP,4
00401411 . 8D55 EC LEA EDX,DWORD PTR SS:[EBP-14]
00401414 . 891424 MOV DWORD PTR SS:[ESP],EDX
00401417 . 89C1 MOV ECX,EAX
00401419 . E8 AEF20300 CALL Q2.004406CC ; second argument
0040141E . 83EC 04 SUB ESP,4
00401421 . 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10]
00401424 . 8945 E4 MOV DWORD PTR SS:[EBP-1C],EAX
00401427 . DB45 E4 FILD DWORD PTR SS:[EBP-1C]
0040142A . B8 00000000 MOV EAX,0
0040142F . BA 00001040 MOV EDX,40100000
00401434 . 894424 08 MOV DWORD PTR SS:[ESP+8],EAX
00401438 . 895424 0C MOV DWORD PTR SS:[ESP+C],EDX
0040143C . DD1C24 FSTP QWORD PTR SS:[ESP]
0040143F . E8 AC9B0100 CALL <JMP.&msvcrt.pow>
00401444 . DD5D D8 FSTP QWORD PTR SS:[EBP-28]
00401447 . 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14]
0040144A . 8945 E4 MOV DWORD PTR SS:[EBP-1C],EAX
0040144D . DB45 E4 FILD DWORD PTR SS:[EBP-1C]
00401450 . B8 00000000 MOV EAX,0
00401455 . BA 00001040 MOV EDX,40100000
0040145A . 894424 08 MOV DWORD PTR SS:[ESP+8],EAX
0040145E . 895424 0C MOV DWORD PTR SS:[ESP+C],EDX
00401462 . DD1C24 FSTP QWORD PTR SS:[ESP]
00401465 . E8 869B0100 CALL <JMP.&msvcrt.pow>
0040146A . DC6D D8 FSUBR QWORD PTR SS:[EBP-28]
0040146D . D97D E2 FSTCW WORD PTR SS:[EBP-1E]
00401470 . 66:8B45 E2 MOV AX,WORD PTR SS:[EBP-1E]
00401474 . B4 0C MOV AH,0C
00401476 . 66:8945 E0 MOV WORD PTR SS:[EBP-20],AX
0040147A . D96D E0 FLDCW WORD PTR SS:[EBP-20]
0040147D . DB5D F4 FISTP DWORD PTR SS:[EBP-C]
00401480 . D96D E2 FLDCW WORD PTR SS:[EBP-1E]
00401483 . 837D F4 00 CMP DWORD PTR SS:[EBP-C],0
00401487 . 79 03 JNS SHORT Q2.0040148C
00401489 . F75D F4 NEG DWORD PTR SS:[EBP-C]
0040148C > C74424 04 8440>MOV DWORD PTR SS:[ESP+4],Q2.00474084 ; ASCII "->"
00401494 . C70424 802F470>MOV DWORD PTR SS:[ESP],Q2.00472F80
0040149B . E8 F4460600 CALL Q2.00465B94
004014A0 . 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C]
004014A3 . 891424 MOV DWORD PTR SS:[ESP],EDX ; looks like edx holds the calculated value
004014A6 . 89C1 MOV ECX,EAX
004014A8 . E8 E70E0400 CALL Q2.00442394
004014AD . 83EC 04 SUB ESP,4
004014B0 . C74424 04 8740>MOV DWORD PTR SS:[ESP+4],Q2.00474087 ; ASCII "

"
004014B8 . 890424 MOV DWORD PTR SS:[ESP],EAX
004014BB . E8 D4460600 CALL Q2.00465B94
004014C0 .^E9 25FFFFFF JMP Q2.004013EA

Kayaker
November 19th, 2013, 02:55
FPU rounding errors seem likely. I noticed a few patterns, multiples of 5 seem to produce errors when paired with 0 and reversed, so do many (but not all) multiples of 11 (11,22,33,...but not 99) and 13 (13,26,39,...). There may be others as well.

I'd be tempted to script the program with a shell execute (or use the relevant code with the pow function separately) and log the results of 0-100 to see if you can find a pattern.

Googling for pow() precision I saw a reference to this

What Every Computer Scientist Should Know About Floating-Point Arithmetic
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

http://stackoverflow.com/questions/16923249/unusual-output-from-pow

Maybe you can blow away your prof with some heady explanation, or even better, improve the implementation so pow() returns consistent results