Dailydave mailing list archives

Re: add %ebx, (%esi)


From: "Berend-Jan Wever (SKYLINED)" <bjwever () microsoft com>
Date: Fri, 20 Jul 2007 13:36:32 +0100

Hi all,

I got a few questions about the three instructions, so here you go:
011E            ADD DWORD PTR DS:[ESI],EBX
015E 00         ADD DWORD PTR DS:[ESI],EBX
019E 00000000   ADD DWORD PTR DS:[ESI],EBX

What you're really coding is:
015E 00         ADD DWORD PTR DS:[ESI+0x00],EBX
019E 00000000   ADD DWORD PTR DS:[ESI+0x00000000],EBX

But why limit yourself to one instruction to get the job done?
8706            XCHG DWORD PTR DS:[ESI],EAX
8D0418          LEA EAX,DWORD PTR DS:[EAX+EBX]
8706            XCHG DWORD PTR DS:[ESI],EAX
The above code does exactly the same with entirely different bytes. You can create more variations using other 
registers than EAX and/or add the 0 BYTE or DWORD offset as with the first two variations.

Here's another way of doing it:
031E            ADD EBX,DWORD PTR DS:[ESI]
871E            XCHG DWORD PTR DS:[ESI],EBX
2B1E            SUB EBX,DWORD PTR DS:[ESI]
F7DB            NEG EBX
The number of variations of achieving the same thing is actually very large. It would be nice to be able to determine 
how many variations there are in total. I'm only interested in variations that don't use "nop" instructions that don't 
do anything useful. There must be a way to do it and prove that you've got all of them.

You can also use knowledge of the (static) contents of registers and memory for even more variations:
If EAX = 0:
011C30          ADD DWORD PTR DS:[EAX+ESI],EBX
011C46          ADD DWORD PTR DS:[ESI+EAX*2],EBX
011C86          ADD DWORD PTR DS:[ESI+EAX*4],EBX
If EAX = 0xDEADBEEF:
019C30 11415221 ADD DWORD PTR DS:[EAX+ESI+0x21524111],EBX

Finally, if you know a register or memory location does not hold a value you need to save, you can use that register or 
memory to create even more variations:
Using stack:
FF36            PUSH DWORD PTR DS:[ESI]
3E:011C24       ADD DWORD PTR DS:[ESP],EBX
8F06            POP DWORD PTR DS:[ESI]

If you want to generate this kind of assembler automatically, you will need a very abstract programming language that 
allow you to describe WHAT you want to achieve instead of HOW you want to do it. The more abstract you can be in your 
description, the more room you leave to the compiler to choose and order the instructions that do what you want.
If you were to implement this, you should be able to generate output code that adheres to the strictest limitations on 
the available characters in the instructions. You will of course need a few instructions that allow you to do 
something, eg. you'll never get anything done using only the NOP instruction. I'd be interested to know what the 
smallest set of characters is that one can possibly code a working program in.

I'd also be very interested in comparing code generated by such a compiler to code I created manually for, for 
instance, ALPHA2's alphanumeric shellcode decoders and see where it can be improved.

Cheers,

SkyLined

Berend-Jan "SkyLined" Wever | Security Software Engineer | SWI-UK | mobile: +44 7790 755 813 | email: mailto:SkyLined 
() microsoft com


-----Original Message-----
From: dailydave-bounces () lists immunitysec com [mailto:dailydave-bounces () lists immunitysec com] On Behalf Of Dave 
Aitel
Sent: Thursday 19 July 2007 19:12
To: dailydave () lists immunitysec com
Subject: Re: [Dailydave] add %ebx, (%esi)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Bee Binger wrote:
I was messing around with your assembler.py and found a couple
points of interest.

When using the 'bt' instruction the assembler throws the "error
..(sorry)" message.  I was sending part of my sys_select code into
the app and my fd_isset uses the bt instruction to check if a fd is
set and it seems the script did not know this instruction. ( not a
bug but would make me have to rewrite a bit of my socket apps )

Also it seems to throw that same error on many "rep" operations ( I
couldnt find a valid combination of registers/rep instructions
without getting the error thrown )

"rep movsb" works for me. I'm not sure we support this very well
though. Piotr noticed we don't do 16 bit addressing very well at all.
Which so far hasn't hurt us, since our shellcode doesn't use it. This
is very much a shellcode/proglet assembler. I added bt this morning,
so that should work nicely for you now. For bonus credit I added
bswap. :> Also Skylined pointed out there are three add %ebx, (%esi)
possibilities, not two.

This last part was more my curiosity than anything but it is making
me wonder alot..

for the default xor %eax,%eax in the textbox I was expecting to see
31 and c0 for the opcodes but  I saw  0x33 and 0xc0. I looked at
the intel manuals and it said:

31 / r     XOR r/m32,r32 r/m32     XOR r32 33 / r     XOR r32,r/m32
r8         XOR r/m8

There was also similar results with the add, sub, and other math
instructions in your script always using the r32 choice as the left
operand instead of the r/m32. Is this some optimization trick?  If
both are registers then they would use the same amount of clock
cycles, but it seems to be limited only register manipulation and
not addresses. I couldnt figure out how in the text box to declare
sections because I was wondering if  31 would be produced for xor
if a variable from the.data section was the source operand since it
seems 33 would break on this or not be allowed.

You can't really define sections for this assembler - but we haven't
had any problems. Let me know if there's something wacky here about
the x86 arch I didn't understand properly. We have been using a
similar (though much slower) assembler for a few years now in all of
our exploits (which is why I can finish an assembler in a week, rather
than a month or two). Once the C parser is rewritten, I'll release it
all as LGPL and you can fix it :>.

I really like the idea of a web service for shellcode decoder
creation. This was part of the original idea for the CANVAS World
Service (which we're still going to do some day). One of the major
advantages is that people who invest lots of time for their own
customized polymorphic decoders could offer them as a web service
attached to CANVAS World Service and then charge a buck every time
they are used, for example. And having them as a web service also
means IDS companies can't easily write signatures, since you can
change them every day and they never see the code that generates the
shellcode decoder itself.

For now, having an assembler web service is pretty fun. :>

- -dave
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFGn6mLB8JNm+PA+iURApXtAJsEXfRAedswtwHYk+AJ7D7WPmjF5ACeJnYZ
5FEJBd+5ubFCJCXSYQOkReE=
=RiFT
-----END PGP SIGNATURE-----

_______________________________________________
Dailydave mailing list
Dailydave () lists immunitysec com
http://lists.immunitysec.com/mailman/listinfo/dailydave
_______________________________________________
Dailydave mailing list
Dailydave () lists immunitysec com
http://lists.immunitysec.com/mailman/listinfo/dailydave


Current thread: