Log in

View Full Version : Fun with prefetch and movsb


omega_red
June 22nd, 2005, 07:14
I was playing with my ever-unfinished crackme and found that it crashes for no apparent reason in about 10% of runs. After some investigations I found that rep movsb can be dangerous

Code:
format PE CONSOLE
entry start

include '%fasminc%\win32a.inc'

;------------------------------------------------
use = ExitProcess
section '' code data readable writeable executable
;------------------------------------------------
start:

mov ecx, 0x90909090 ; nops
mov [a_1], ecx
mov [a_1+4], ecx
mov [a_1+8], ecx
mov [a_1+12], ecx
mov ecx, (data_end-data_start)
mov esi, data_start
mov edi, a_1
rep movsb

; nop ; uncomment this to prevent crashes

a_1:
times 0x10 db 0xcc ; fake int3, will be replaced by NOPs
nop
ret

;------------------------------------------------

data_start:
; nop
jmp $+2
; nop
jmp $+2
data_end:

;------------------------------------------------

align 4
data import

library kernel,'kernel32.dll'

import kernel,\
ExitProcess,'ExitProcess'

end data

(FASM format)

This innocent piece of code can crash randomly. Why? It's easy to see if we have JIT debugger assigned and analyze program's state upon crash:

Code:
00401031 0090 90909090 ADD BYTE PTR DS:[EAX+90909090],DL
00401037 90 NOP
00401038 90 NOP
00401039 90 NOP


As can be seen, EIP "slipped" by 1 byte, hence the error.

Interestings things pop up while we are debugging this with Olly. Tracing by F7 and F8 gives different results. F8 on REP = program exits, code is incorrect:

Code:
0040102C |. F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
0040102E |. 90 NOP
0040102F |. 00EB ADD BL,CH
00401031 |. 0090 90909090 ADD BYTE PTR DS:[EAX+90909090],DL
00401037 |. 90 NOP
00401038 |. 90 NOP


And with F7 all is OK.
I observed those effects only with movsb - ...w and ...d seem to not behave like this (f8 on movsw causes program halt too, but code is copied OK).

As a bonus, Olly seems to have a bug in handling such SMC. You can see it by F7-ing, after MOVSB selecting lines looks weird

And for last, something that made me really confused - EXE in CONSOLE format crashes (EIP "slip" much more often than the GUI one.

My CPU: Intel P4 3.2 HT (enabled). OS: Win XP SP2.

[edit] Link for compiled exe: http://212.33.90.248/~omega/p.exe

blabberer
June 22nd, 2005, 08:20
well iwas reading this i didnt get it so thought ill assemble it in place and see

loaded iczelion tut-02 aka msgbox

typed in this code
Code:

00401000 msgboxor.<ModuleEntr>MOV ECX, 90909090
00401005 MOV DWORD PTR DS:[<a_1>], ECX
0040100B MOV DWORD PTR DS:[<a_1+4>], ECX
00401011 MOV DWORD PTR DS:[<a_1+8>], ECX
00401017 MOV DWORD PTR DS:[<a_1+12>], ECX
0040101D MOV ECX, 6 (manual calc here)
00401022 MOV ESI, OFFSET <msgboxor.data_start>
00401027 MOV EDI, <msgboxor.a_1>
0040102C REP MOVS BYTE PTR ES:[EDI], BYTE PTR>
0040102E <msgboxor.a_1> INT3
0040102F INT3
00401030 INT3
00401031 INT3
00401032 <msgboxor.a_1+4> INT3
00401033 INT3
00401034 INT3
00401035 INT3
00401036 <msgboxor.a_1+8> INT3
00401037 INT3
00401038 INT3
00401039 INT3
0040103A <msgboxor.a_1+12> INT3
0040103B INT3
0040103C INT3
0040103D INT3
0040103E INT3

00403000 <msgboxor.data_start> 90 EB 00 90 EB 00 6F 6E 27 73 20 74 75 74 6F 72 ..on's tutor

did view executable --> modify .text section attributes to e0000020 from 60000020

saved it reopened and f7ned works good
f8 it works good

after f8 the last time it looks like this

Code:

00401000 msgboxor.<ModuleEntr>MOV ECX, 90909090
00401005 MOV DWORD PTR DS:[<a_1>], ECX
0040100B MOV DWORD PTR DS:[<a_1+4>], ECX
00401011 MOV DWORD PTR DS:[<a_1+8>], ECX
00401017 MOV DWORD PTR DS:[<a_1+12>], ECX
0040101D MOV ECX, 6
00401022 MOV ESI, OFFSET <msgboxor.data_start>
00401027 MOV EDI, <msgboxor.a_1>
0040102C REP MOVS BYTE PTR ES:[EDI], BYTE PTR>
0040102E <msgboxor.a_1> NOP
0040102F JMP SHORT msgboxor.00401031
00401031 NOP
00401032 <msgboxor.a_1+4> JMP SHORT msgboxor.00401034
00401034 NOP
00401035 NOP
00401036 <msgboxor.a_1+8> NOP
00401037 NOP
00401038 NOP
00401039 NOP
0040103A <msgboxor.a_1+12> NOP
0040103B NOP
0040103C NOP
0040103D NOP
0040103E INT3



am i missing some thing ???

also if it is smc dont use autostart analysis of main module option
or if you have it right click and remove analysis and hit ctrl+a and do reanalysis if at all you need analysis

also may be you could post a small prototype binary so that our codes tally and we talk of same problem

and repmovs f8 means olly sets an internal oneshot breakpoint on the next command
if you modify it with smc then olly should be going nuts trying to restore old opcode

Quote:

0012BED8 006701F6 hOwner = 006701F6 ('OllyDbg - msgboxor.exe - [CPU...',class='OLLYDBG')
0012BEDC 0012BEEC Text = "OllyDbg set byte at address 0040102E to CC (code of command INT3, use
0012BEE0 004B2546 Title = "Breakpoint corrupted!"
0012BEE4 00000014 Style = MB_YESNO|MB_ICONHAND|MB_APPLMODAL
0012BFF8 004194A5 OLLYDBG.00418C4C


added the modified binary as attachment you can f7,f8,f9 it if you f9 it will stop on the last unmodified int3 and jit will break into action

omega_red
June 24th, 2005, 04:16
I have made some tests. It seems that this code crashes only on P4 CPUs!

Quote:
[OK]
# Celeron 2.40
Max CPUID: 5
Vendor ID: GenuineIntel
Version: 00000f34
(type 0, family 15, model 3, stepping 4)
Features: bfebfbff (ebx=00010800, ecx=00017437)

# Celeron 2.0
Max CPUID: 2
Vendor ID: GenuineIntel
Version: 00000f29
(type 0, family 15, model 2, stepping 9)
Features: bfebfbff (ebx=0001080a, ecx=00017408)

# Celeron 1.8
Max CPUID: 2
Vendor ID: GenuineIntel
Version: 00000f13
(type 0, family 15, model 1, stepping 3)
Features: 3febfbff (ebx=0001080a, ecx=00000000)

# Sempron
Max CPUID: 1
Vendor ID: AuthenticAMD
Version: 00000fc0
(type 0, family 15, model 12, stepping 0)
Features: 078bfbff (ebx=00000800, ecx=00000000)


[Crash]
# P4 3.2 HT enabled
Max CPUID: 5
Vendor ID: GenuineIntel
Version: 00000f34
(type 0, family 15, model 3, stepping 4)
Features: bfebfbff (ebx=00020800, ecx=00017437

# P4 3.0
Max CPUID: 5
Vendor ID: GenuineIntel
Version: 00000f33
(type 0, family 15, model 3, stepping 3)
Features: bfebfbff (ebx=00020800, ecx=00001053)

# P4 3.0 HT enabled
Max CPUID: 3
Vendor ID: GenuineIntel
Version: 00000f41
(type 0, family 15, model 4, stepping 1)
Features: bfebfbff (ebx=00020800, ecx=00017437)

nikolatesla20
June 25th, 2005, 04:49
You can actually use differing version of SMC like this to determine CPU..

hxxp://www.assembly-journal.com/viewarticle.php?id=109&layout=html

and scroll down


You could probably do a far jump to clear the queue before it gets to the modded code?

Also, hypterthreading, through my experience, has much troubles. To prevent this, add API calls to your little app to force it to one CPU. Use the SetProcessAffinityMask API.


-nt20

omega_red
June 27th, 2005, 03:09
Yes, I suspected HT to be main reason for this... But SetProcessAffinityMask doesn't alter this behaviour.

Nico
July 1st, 2005, 10:05
Try to put any instruction right under the rep movsb.
It fixes the crash for me.

uncomment your nop for instance.

I have a P4 HT as well.

Nico

omega_red
July 1st, 2005, 10:13
Quote:
[Originally Posted by Nico]Try to put any instruction right under the rep movsb.
It fixes the crash for me.

uncomment your nop for instance.

I have a P4 HT as well.

Nico


Exactly, that's why I put that comment there

Nico
July 1st, 2005, 12:17
You didn't mention that it was working with an instruction after the rep stuff, that's why i thought it could have been a test of some sort.
The way you wrote your post, i thought you didn't know how to fix this issue.

Sorry then ;-)

Nico