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:
- add %ebx, (%esi) Dave Aitel (Jul 17)
- Re: add %ebx, (%esi) Bee Binger (Jul 17)
- Re: add %ebx, (%esi) Dave Aitel (Jul 19)
- Re: add %ebx, (%esi) Berend-Jan Wever (SKYLINED) (Jul 20)
- Re: add %ebx, (%esi) Bee Binger (Jul 20)
- Re: add %ebx, (%esi) Mateusz Berezecki (Jul 20)
- Re: add %ebx, (%esi) Dave Aitel (Jul 19)
- Re: add %ebx, (%esi) Bee Binger (Jul 17)
- <Possible follow-ups>
- Re: add %ebx, (%esi) Bee Binger (Jul 20)