Feature request: assemble instructions

Sep 20, 2011 at 6:10 PM

It would be nice to have ability to assemble custom instructions. Like how "byakugan" extension "!jutsu searchOpcode" allows (with the difference that there is no need in separators, just pure opcodes). This extension source code can give some clues. Related code is located in "metasploit/external/source/byakugan/jutsu.cpp".

Hope that helps.

Coordinator
Sep 22, 2011 at 6:24 AM
Edited Sep 22, 2011 at 6:24 AM

As I remember yor have installed pre 0.0.20 version. It has assemblay routine. It works as windbg command 'a'. For example:

kd>!pycmd
>>>assembly( reg("eip"), "int 3" )

Is it what you want?

I think, I should move this routine to disasm class. So we can not to pass offset parameter.

kd>!pycmd
>>> dasm  = disasm()   # begin from current IP
>>> dasm.assembly( "pop ebp")
>>> dasm.assembly( "int 3" )

Sep 22, 2011 at 10:45 AM

This is a useful feature too and much closer to what I need, but not exactly.

assembly() would modify register, but I need to preserve it. What I would like to see is the return of raw opcodes. Say, something like this:

opcodes = raw_assembly('xchg esp, eax') 

where opcodes would contain "94".

Now I would have to do lots of actions myself - get old register value and save it, do assembly, parse the output, then restore register.

Coordinator
Sep 22, 2011 at 10:57 AM
Edited Sep 22, 2011 at 10:59 AM

I can not understand what is a "register" you mean? IP ?

Do you want to get a oppcode of any insruction without interacting ( assembly or disassembly) with target memory? Why?

Sep 22, 2011 at 11:55 AM

I need such functionality to search for opcodes in memory. Hence, memory should not be modified (at least for a time when I search in it). 

If it would be possible to assemble custom instructions and get their opcodes without side-effects we are discussing, then it would make opcode search very convenient. Generally, this is needed for ROP.

Coordinator
Sep 22, 2011 at 12:41 PM
Edited Sep 22, 2011 at 12:41 PM

I think you can use disasm + loadBytes.

Something in the such way:

dasm = disasm( functionBegin )
opCodes = []

for dasm.instruction() != "ret": 
    dasm.next()
    opCodes.append( ( dasm.instruction(), loadBytes( dasm.current(), dasm.length() ) )

#opCodes contains list: [ ( "834ae06d 5f              pop     edi", [ 0x5f] ), ("834ae070 8be5            mov     esp,ebp", [0x8b, 0xe5] ) ]

Then you can analyze opCodes list by your algorithm.  

Sep 22, 2011 at 1:26 PM

Well, such functionality was already implemented, but that's insufficient. ROP was a basic example, there is a need also for jump-oriented programming - one have to find instructions that ends with "call [edx+offset]" or "jmp eax", etc. Approach that you offer requires a lot of hand-work and is limited - I still have to look and search for useful sequences manually. Currently I have written wrapper for !jutsu - it executes extension command and saves to text files chunks of code, but my aim is to automate search and do that without help of external extensions like !jutsu.

So, I simply need to get opcode from instruction - that would give me opportunity to extend and customize search exactly how I need.

Coordinator
Sep 22, 2011 at 2:25 PM

Such functionality is beyond the goal of our project. Pykd implements access to target process/system for debugging. So pykd can control debugger and read memory and regsiters through Debug Engine. There is some sugar for developper:  types, modules e.t.c. But unfortunatly it's almost all.  If you want to find code signatures in target memory, pykd can get access to the memory and reads it as raw bytes or disassembled instruction's stream. But we don't plan make own assembler/emulator on python. It is very intersting task, but we have no resources for it.  I'm sure, there are projects for finding exploitable code.


Sep 22, 2011 at 2:42 PM

Ok, thanks. Will try to find a solution still within PyKd.

Coordinator
Sep 22, 2011 at 3:08 PM

if you have any idea how it can be solved with Debug Engine, without implementing opcode tables - write me and I will add such functionality