SunBeam Posted June 25, 2009 Posted June 25, 2009 Hi guys. It's me again, with another kinky weird request from y'allz. Do you happen to know the fastest way to clear all registers? (e-a-c-d-b-x, e-s-d-i)I wrote something like this, keeping in mind I want code to be small:_WIPE proc push 6h pop ecx @loop: push 0 loop @loop pop eax pop ecx pop edx pop ebx pop esi pop edi ret_WIPE endpPretty much looks like a Delphi function in prolog, lol. Post your thoughts, please!
metr0 Posted June 25, 2009 Posted June 25, 2009 (edited) What about that one (makes assumptions concerning the stack, you should mind zeroing it manually via rep movsd)? sub esp, 0x20mov dword ptr [esp - 0x0c], espsub dword ptr [esp - 0x0c], 0x20popadedit: Didn't save ebp though you intended to keep it as well, try that one:mov dword ptr [esp - 0x18], ebpmov dword ptr [esp - 0x14], espsub esp, 0x20popad Edited June 25, 2009 by metr0
SunBeam Posted June 25, 2009 Author Posted June 25, 2009 (edited) Actually, I will modify my function with this :-)_WIPE procpush 6hpop ecx@loop:push 0loop @looppopad // :-)))ret_WIPE endpEDIT: Didn't know ESP and EBP are also pushed to stack on a PUSHAD o_O Edited June 25, 2009 by SunBeam
metr0 Posted June 25, 2009 Posted June 25, 2009 Keep in mind you're pushing six zero dwords, though popping eight values from the stack. Plus, you zero ebp and esp, not sure if you want to save them?
SunBeam Posted June 25, 2009 Author Posted June 25, 2009 (edited) Yeah, I did PUSH 8. And It wiped all but ESP on a POPAD.. Thing is I want to keep ESP and EBP from being emptied.. Edited June 25, 2009 by SunBeam
GamingMasteR Posted June 25, 2009 Posted June 25, 2009 Hi,You want fastest or smallest method ?Because loops are never fast ...XOR -> 1 ClockPUSH+POP -> 1+1 = 2 ClocksXOR wins
SunBeam Posted June 25, 2009 Author Posted June 25, 2009 (edited) Smallest I meant, my bad :-) The smallest code possible.. Or, how to say this, the most COMPACT method that can be written in a few lines (2-3 lines if possible)..P.S.: Wish there was a CASE option for registers, LOL. Like:--push 4hpop ecx@loop_1:push 0loop @loop_1@loop_2:case (a..d) X:pop eXxloop @loop_2Looks like crap, but wish there was something like that :-) Or..eAx -> inc "A" == B -> eBx -> inc "B" == C -> eCx .. Edited June 25, 2009 by SunBeam
metr0 Posted June 25, 2009 Posted June 25, 2009 Well, that'd greatly enhance code obfuscation possibilities, for sure!
Peter Ferrie Posted June 25, 2009 Posted June 25, 2009 Try this:push ebppushadfnsave [esp-4ch]popadpop ebp8 bytes, preserves ebp.
Ufo-Pu55y Posted June 25, 2009 Posted June 25, 2009 fnsave [esp-4ch]idea's cool, but what if u got stuff in ST(?) ? oO
SunBeam Posted June 25, 2009 Author Posted June 25, 2009 @UFO: I'm coding a tool, so there won't be anything there in ST(?) ;-)
SunBeam Posted June 26, 2009 Author Posted June 26, 2009 Just wanted to add Peter's trick is pretty neat :-) Here's a little glimpse:
Peter Ferrie Posted June 26, 2009 Posted June 26, 2009 :-) If, for some reason, the FPU were in use, then you can do it in a really obvious way:push 0pop eaxpush eaxpush eaxpush eaxpush eaxpush eaxpush ebppush eaxpush eaxpopadbut it's 12 bytes and lots of lines. FPU will be empty on process start because the context is set that way.
SunBeam Posted June 26, 2009 Author Posted June 26, 2009 I had to hit the exception from the rule, Peter. Here's the source code: .586p.mmx .model flat, stdcalloption casemap :noneinclude \masm32\include\windows.incinclude \masm32\include\user32.incinclude \masm32\include\kernel32.incinclude \masm32\include\masm32.incinclude \masm32\include\comctl32.incinclude \masm32\macros\macros.asmincludelib \masm32\lib\user32.libincludelib \masm32\lib\kernel32.libincludelib \masm32\lib\comctl32.libincludelib \masm32\lib\masm32.lib.databText db "Result: ",0.data?bSpot dd ?.codeRegWipe proc push ebp pushad fnsave [esp-4ch] popad pop ebp retRegWipe endpDisplay proc fn lstrcpy, addr bSpot, hex$(ebx) fn lstrcat, addr bText, addr bSpot fn MessageBox, 0, addr bText, "Boing!", MB_OK OR MB_ICONINFORMATION fn RtlZeroMemory, addr bText+0Ah, 10h retDisplay endpFuncA proc mov AX,171 sub AX,154 mov CX,AX shl AX,2 sub AX,CX mov BL,AL call Display call RegWipe retFuncA endpFuncB proc mov BX,101 mov CL,42h sub BX,13h shr CX,1 sub BL,CL call Display call RegWipe retFuncB endpFuncC proc mov AX,13h mov BX,3 mul BL mov BL,AL call Display call RegWipe retFuncC endpFuncD proc mov CX,7 mov AX,0C8h idiv CL add AL,01Bh mov BL,AL call Display call RegWipe retFuncD endpFuncE proc mov CX,12h sub CX,0Ah shl CX,1 mov BX,CX shl CX,2 add CX,BX sub CL,5 mov BL,CL call Display call RegWipe retFuncE endpmain proc fn InitCommonControls call RegWipe call FuncA call FuncB call FuncC call FuncD call FuncE @end: retmain endpend main Main RegWipe caller: FPU state before calling RegWipe inside FuncA: And afterwards :-( Kinda owned me :-)
Ufo-Pu55y Posted June 26, 2009 Posted June 26, 2009 You don't seem to load any wicked DLL.. anyway wanted to mention it. I once tried using FPU and MMX at the same time lol, so I remember them using the same REGs.Just import any DLL which uses for instance mmx stuff in its init code or whatever.. and there you go.. f* up FPU REGs ^^
Peter Ferrie Posted June 27, 2009 Posted June 27, 2009 It might also be Olly parsing something and changing the context.You can add a fninit before the wipe. It adds only two bytes, and guarantees that the context is clean, at least at that moment.There's also the possibility that single-stepping will give you a different result from just running directly (I know of an FPU-related single-step vs run anti-debugging trick, but this isn't it).Also inside vs outside of a debugger. Could be a nice anti-debugging trick, if that is the case. ;-)
Sub Xero Posted June 27, 2009 Posted June 27, 2009 You could do this, which is a slight modification to just XORing all the registers.XOR ECX,ECXMUL ECXXOR EBX,EBXXOR ESI,ESIXOR EDI,EDIIt's only 10 bytes and eveything else is preserved.Sub Xero
SunBeam Posted June 27, 2009 Author Posted June 27, 2009 (edited) ^ Good one ;-) And the FINIT thingie didn't do the trick. Plus it happens both in Olly and outside of it, so it's not a debugger-only behavior.P.S.: Had a little typo in the source above:fn RtlZeroMemory, addr bText+08h, 8h // fixed Edited June 27, 2009 by SunBeam
Ksbunker Posted July 14, 2009 Posted July 14, 2009 I prefer ClearRegs! ClearRegs MACRO .data zer dd 0,0,0,0,0,0,0,0, zer .code xchg esp, [zer+8*4] popad pop esp ENDM ClearRegs1 MACRO push 32 pop ecx sub esp, ecx mov edi, esp xor eax, eax rep stosb popad ENDM
ghandi Posted July 15, 2009 Posted July 15, 2009 To be honest, unless you have this in a loop (read: bruteforce) you wont notice the difference. If this was used in something which was time critical and was being executed millions of times, then you'd worry about clock cycles, latency and how well you can fit instructions in the pipeline to take advantage of OOE (out of order execution).If you have a small loop that is executed many times, where the code is small enough to fit into the L1 cache, then you'll notice a difference, but otherwise most options to clear your registers will execute in a nanosecond anyway.The MASM32 forum is a good place for information about instruction speeds, etc.HR,Ghandi
av999 Posted July 15, 2009 Posted July 15, 2009 xchg esp,[point_bottom_zero_mem]popadxchg esp,[point_bottom_zero_mem]
SunBeam Posted August 6, 2009 Author Posted August 6, 2009 (edited) @ghandi: This isn't about speed, but about SHORTER ways to do it (smaller code)@ksbunker: Didn't know of one such macro. It's written by yourself?@av999: Will try that one out. Feedback soon enough..EDIT1: av999, any way to preserve EBP as well?EDIT2: Did something like this...dataszPtr dd szStuff.data?szStuff dd 20h dup(0)RegWipe PROC xchg dword ptr ds:[szPtr],esp popad xchg dword ptr ds:[szPtr],esp mov ebp,esp add ebp,4 retRegWipe ENDP Edited August 6, 2009 by SunBeam
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now