cea-sec / miasm

Reverse engineering framework in Python
https://miasm.re/
GNU General Public License v2.0
3.48k stars 474 forks source link

disable emulated standard library loading for x64 machines #406

Closed kamou closed 8 years ago

kamou commented 8 years ago

Hello, is there a way to disable loading of the emulated standard library APIs for x64 ? As the currently implemented ones are based on x86, this causes some issues.

Would be better to raise a ValueError("unknown api") excpetion when calling them, rather then crashing and trying to figure out which API needs to be reimplemented.

kamou commented 8 years ago

I tried changing linuxstlib.py so the xxx APIs check for the current machine name, but it happens that the machine is not accessible from the jitter module.

serpilliere commented 8 years ago

I may not have fully understood your question. The code in linux_stdlib.py should not depend on the architecture: it uses wrappers which will mask the architecture (or api) We are currently working on a better api manager (see #355)

But maybe this can help:

>>> jitter.arch.name
'x86'
>>> jitter.attrib
32

Does it help?

kamou commented 8 years ago

perfect yes, it should help. but FYI, xxx_puts is not working properly in Sandbox_x86_64. so if you say linux_stdlib.py is supporting the x86 64 calling convention then I guess there must be a bug somewhere.

kamou commented 8 years ago

(maybe in my code, got to check)

itsacoderepo commented 8 years ago

Hi kamou,

the reason why puts doesn't work is here (https://github.com/cea-sec/miasm/blob/214024052d21c325eae7075f8965da5e244704dd/miasm2/arch/x86/jit.py):

    @named_arguments
    def func_args_stdcall(self, n_args):
          args_regs = ['RCX', 'RDX', 'R8', 'R9']

So if you compile the code below, you see that the paramter "test" is not provided by any of the above register.

#include <stdio.h>
#include <string.h>
int main()
{
    puts("test");
}
$ gcc /tmp/putstest.c -o putstest -O0
$ objdump -d -M intel /tmp/putstest
...
00000000004004e6 <main>:
  4004e6:   55                      push   rbp
  4004e7:   48 89 e5                mov    rbp,rsp
  4004ea:   bf 84 05 40 00          mov    edi,0x400584
  4004ef:   e8 cc fe ff ff          call   4003c0 <puts@plt>

If you run this code on the compiled binary, everything will be fine. See that i changed the line from "index = args.s" (as in linux_stdlib.py) to "index = jitter.cpu.EDI" (jitter.cpu.RDI is working too):

import os
from pdb import pm
from miasm2.analysis.sandbox import Sandbox_Linux_x86_64
from sys import stdout

# Python auto completion
filename = os.environ.get('PYTHONSTARTUP')
if filename and os.path.isfile(filename):
    execfile(filename)

def xxx_puts(jitter):
    '''
    #include <stdio.h>
    int puts(const char *s);
    writes the string s and a trailing newline to stdout.
    '''
    ret_addr, args = jitter.func_args_stdcall(['s'])
    index = jitter.cpu.EDI
    char = jitter.vm.get_mem(index, 1)
    while char != '\x00':
        stdout.write(char)
        index += 1
        char = jitter.vm.get_mem(index, 1)
    stdout.write('\n')
    return jitter.func_ret_stdcall(ret_addr, 1)

# Parse arguments
parser = Sandbox_Linux_x86_64.parser(description="PE sandboxer")
parser.add_argument("filename", help="PE Filename")
options = parser.parse_args()

# Create sandbox
sb = Sandbox_Linux_x86_64(options.filename, options, globals())
sb.run(0x4004e6)
$ python2 putsjitter.py putstest -j gcc
[WARNING]: Create dummy entry for 'xxx.dll'
[INFO]: xxx_puts(s=0x0) ret addr: 0x4004f4
test

best regards

kamou commented 8 years ago

thanks @itsacoderepo , but wouldn't it be better to change ? ['RCX', 'RDX', 'R8', 'R9'] to ['RDI', 'RSI, 'RDX', 'RCX', 'R8', 'R9']

Or maybe there's a reason for that ?

kamou commented 8 years ago

ok, just saw #355. there is currently no support for multiple calling conventions... thanks all for the clarifications

serpilliere commented 8 years ago

Good analysis @itsacoderepo ! And correct @kamou : you have to overwrite the func_args_stdcall (or just the list) to support the new ABI.

We are currently (with @commial ) working on a generic way to support multiples ABI. And maybe one day closing the #355 :smile:

May I close the issue, as it's a dup of the #355 ?

kamou commented 8 years ago

sure !