Weird Stuff

As I am still working on TinyPE NG very hard, I got it to 220 bytes at the moment. I am still not frustrated and I think I will be able to get it a few bytes less. Since my last post, I was talking with Peter Ferrie on the Code Crunchers mailing list, which you’re invited to sign up right here. So Peter suggested that I won’t use WinExec, that instead of executing the downloaded file, which was an .exe by then. I should download a .dll file and LoadLibrary it. Thing was, that I didn’t use LoadLibrary, that was one of the tricks in the new version. Eventually, I removed lots of code (18 bytes so far!) and managed to download the .dll and load it using an export forwarding, but this time on the downloaded file! And then it even spared the ExitProcess trick (one byte…) that I came up with Matthew Murphey in the last challenge. I don’t need to ExitProcess since now the dll is loaded into the same process, and ExitProcess in the dll itself will do the job… My only problem was that my server didn’t let me download any file with an extension of ‘.dll’. I got freaked out and didn’t understand why the damned thing won’t let me download it. So I tried to remove the access list in .htaccess and play with it, but nothing helped. So I almost wanted to give up with the whole idea. Until at the last moment, I thought that since my server is Linux based (so why does it care about dll files in the first place?) I can call the file “.DLL”, notice the capital letters. Now the loader doesn’t really care about big or small letters so everything went ok then…

To a different matter now, a friend (who contributed to diStorm in the past), keeps on using it heavily himself and found something interesting. He was trying to exchange two registers, eax and r8d (xchg eax, r8d). That would be something with the REX prefix (specifially 41) and 90 following. The thing was that no matter what you’re doing (that is prefixing 90 with any byte) it won’t change it’s behavior. It’s like 90 is really hardwire for doing nothing (no-operation). Ahh sorry, 90 is xchg eax, eax which is used to denote a NOP instruction for those who were following me. So image you want to exchange two registers and the assembler generated 41 90 – nothing happens when you run it. Quite absord. So it has to be changed into the 2 bytes of the exchange instruction… The cool thing about this whole story that diStorm showed the output well: DB 0x41; NOP. Now to be honest, I never gave it a thought when I ported diStorm to support the 64 bit instructions. But it so happens that the 0x90 is really being changed to NOP rather than xchg eax, eax. So the prefix is useless and thus dropped… Anyays a nice finding Stefan!

Oh yeah, well I was not saying the whole truth, there is a prefix for the NOP instruction, 0xf3. Together with 0x90, it becomes a PAUSE instruction…

3 Responses to “Weird Stuff”

  1. anonymous says:

    According to the documentation (both Intel and AMD) 41 90 is xchg eax,rd8. Here is what AMD documentation has to say:

    “The x86 architecture commonly uses the XCHG EAX, EAX instruction (opcode 90h) as
    a one-byte NOP. In 64-bit mode, the processor treats opcode 90h as a true NOP only if
    it would exchange rAX with itself. Without this special handling, the instruction
    would zero-extend the upper 32 bits of RAX, and thus it would not be a true nooperation.
    Opcode 90h can still be used to exchange rAX and r8 if the appropriate
    REX prefix is used.”

    I also tried this in the debugger (an with an Intel processor)

    0:000> rrax=111;rr8=888
    0:000> eb @rip 41 90 cc
    0:000> g
    (b58.f58): Break instruction exception – code 80000003 (first chance)
    00000000`77d44ea2 cc int 3
    0:000> r
    rax=0000000000000888 rbx=0000000000000000 rcx=0000000077d45cca
    rdx=0000000000000000 rsi=00000000001efa80 rdi=0000000077de2dd0
    rip=0000000077d44ea2 rsp=00000000001ef688 rbp=000007fffffdb000
    r8=0000000000000111 r9=000007fffffdb000 r10=0000000000000000
    r11=0000000000000246 r12=00000000ffae00e0 r13=0000000000000000
    r14=0000000000000000 r15=0000000077d4f2e0
    iopl=0 nv up ei pl zr na po nc
    cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
    00000000`77d44ea2 cc int 3

  2. arkon says:

    Another incompability between the implementations I think…
    AMD’s spec:
    “…Therefore, in 64-bit mode the processor treats opcode 90h (the
    legacy XCHG EAX, EAX instruction) as a true NOP, regardless
    of a REX operand-size prefix.”.

  3. […] Two posts ago I talked about NOP in 64bits. It was unclear whether 0×90 acts as a true NOP. Because if you really think about it, the way 64bits processor works when it executes 32bits operations is to do the exchange between EAX and EAX, and then zero the high dword of RAX. This is why XOR EAX, EAX is similar to XOR RAX, RAX… Only in 64bits! […]

Leave a Reply