Results 1 to 2 of 2

Thread: call_function_raw(), BinaryBuffer functions, dlopen/dlsym/dlclose

  1. #1
    Assadministrator kung foo man's Avatar
    Join Date
    Jun 2012
    Location
    trailerpark
    Posts
    2,011
    Thanks
    2,102
    Thanked 1,084 Times in 753 Posts

    call_function_raw(), BinaryBuffer functions, dlopen/dlsym/dlclose

    BinaryBuffer example:

    PHP Code:

        buf 
    memory_malloc(128);
        
    bb binarybuffer_new(buf);
        
    binarybuffer_write(bb"i"100);
        
    binarybuffer_write(bb"f"0.0123);
        
    binarybuffer_write(bb"s""hello");
        
    binarybuffer_write(bb"d"0.12345);
        
    binarybuffer_write(bb"c""#");
        
    binarybuffer_write(bb"v", (0.10,0.20,0.30));
        
    binarybuffer_seek(bb0);
        
    binarybuffer_read(bb"i");
        
    binarybuffer_read(bb"f");
        
    binarybuffer_read(bb"s");
        
    binarybuffer_read(bb"d");
        
    binarybuffer_read(bb"c");
        
    binarybuffer_read(bb"v");
        
    printf("bb=% i=% f=% s=% d=% c=% v=%\n"bbifsdcv);
        
    memory_free(buf);
        
    binarybuffer_free(bb); 
    Output:
    Code:
    bb=164778640 i=100 f=0.012 s=hello d=0.123 c=# v=(0.10, 0.20, 0.30)
    Use cases:
    • prepare arguments for call_function_raw()
    • parse any binary data, e.g. read player entity data ingame without recompiling libcod (ingame CheatEngine anyone?)


    The strings are actually malloc'ed and only the pointer is saved as 4-byte-value in the binarybuffer. Internally they are saved in a list, so binarybuffer_free() can free them.

    Dynamic Library example:

    PHP Code:
        libc dlopen("libc.so.6");
        
    libc_printf dlsym(libc"printf");
        
    printf("libc=% libc_printf=%\n"libclibc_printf);
        
    dlclose(libc); 
    Output:
    Code:
    libc=-144867328 libc_printf=-146018720
    Use cases:
    • get function addresses for call_function_raw()



    call_function_raw() example:

    PHP Code:
        buf memory_malloc(128);
        
    bb binarybuffer_new(buf);
        
    binarybuffer_write(bb"s""printf: int=%i float=%f string=%s double=%g char=%c vector=(%.2f,%.2f,%.2f)\n");
        
    binarybuffer_write(bb"i"100);
        
    binarybuffer_write(bb"f"0.0123);
        
    binarybuffer_write(bb"s""hello");
        
    binarybuffer_write(bb"d"0.12345);
        
    binarybuffer_write(bb"c""#");
        
    binarybuffer_write(bb"v", (0.10,0.20,0.30));

        
    libc_printf dlsym(0"printf");
        
    call_function_raw(libc_printf"s.ifsdcfff"buf);

        
    memory_free(buf);
        
    binarybuffer_free(bb); 
    Output:
    Code:
    printf: int=100 float=0.012300 string=hello double=0.12345 char=# vector=(0.10,0.20,0.30)
    Use cases:
    • use all kind of C functions (e.g. from libc, but also from IDA etc.) without recompiling libcod, though atm some shitty prework todo


    It's called "raw", because I wanna do a normal call_function() later, with much less bloat code to prepare the arguments. Kinda automatically, based on stackGetNumberOfParams()/stackGetParamType()

    Regarding: call_function_raw(libc_printf, "s.ifsdcfff", buf);
    Type Explanation
    s string, 4 bytes (just a pointer)
    . varargs kicking in, like printf(char *msg, ...). Needed, because C handles floats like doubles in varargs-call-convention
    i int, 4 bytes
    f float, 4 bytes
    d double, 8 bytes
    c char, 1 byte




    Inb4 ideas, tellz0r!

    GitHub Commit: https://github.com/kungfooman/libcod...8ff9127dc15f16
    Download of precompiled binaries: http://killtube.org/downloads/libcod/2015.01.17/
    timescale 0.01

  2. The Following 2 Users Say Thank You to kung foo man For This Useful Post:

    php (17th January 2015),voron00 (18th January 2015)

  3. #2
    Assadministrator kung foo man's Avatar
    Join Date
    Jun 2012
    Location
    trailerpark
    Posts
    2,011
    Thanks
    2,102
    Thanked 1,084 Times in 753 Posts
    Ok, a "nicer" call_function, done with CoDScript only:

    PHP Code:
    call_function(function, signatureabcdefghijkl) {
        
    args = [];
        
    args[args.size] = a;
        
    args[args.size] = b;
        
    args[args.size] = c;
        
    args[args.size] = d;
        
    args[args.size] = e;
        
    args[args.size] = f;
        
    args[args.size] = g;
        
    args[args.size] = h;
        
    args[args.size] = i;
        
    args[args.size] = j;
        
    args[args.size] = k;
        
    args[args.size] = l;
        
        
    buf memory_malloc(128);
        
    bb binarybuffer_new(buf);
        
        
    signatureClean ""// without the . (varargs-marker)
        
    for (ii=0ii<signature.sizeii++)
            if (
    signature[ii] != ".")
                
    signatureClean += signature[ii];
        
        
    signature_pos 0;
        for (
    ii=0ii<args.sizeii++) {
            
    //printf("ii=% type=%\n", ii, getType(args[ii]));

            
    needGuessType ii >= signatureClean.size;
            
    //printf("ii=%, sigClean.size=% needGuessType=%\n", ii, signatureClean.size, needGuessType);
            
    if ( ! needGuessType) {
                
    // don't guess type when it's given in signature
                
    binarybuffer_write(bbsignatureClean[ii], args[ii]);
                continue;
            }
            
            
    type "";
            switch (
    getType(args[ii])) {
                case 
    "INT":    type "i"; break;
                case 
    "STRING"type "s"; break;
                case 
    "FLOAT":  type "f"; break;
            }
            
    signature += type// only add missing types to signature
            
    binarybuffer_write(bbtypeargs[ii]); // add data with our guessed type
        
    }

        
    //printf("Function: % Signature: %\n", function, signature);
        
    ret call_function_raw(function, signaturebuf);
        
        
    memory_free(buf);
        
    binarybuffer_free(bb);
        
        return 
    ret;

    Call like:

    PHP Code:
        call_function(libc_printf"s.""hi!!! int=%d float=%f string=%s\n"1230.345"yo"); 
    Output (with debug messages):

    Code:
    ii=0 type=STRING
    ii=1 type=INT
    ii=2 type=FLOAT
    ii=3 type=STRING
    ii=4 type=UNDEFINED
    ii=5 type=UNDEFINED
    ii=6 type=UNDEFINED
    ii=7 type=UNDEFINED
    ii=8 type=UNDEFINED
    ii=9 type=UNDEFINED
    ii=10 type=UNDEFINED
    ii=11 type=UNDEFINED
    Function: -146088352 Signature: s.ifs
    hi!!! int=123 float=0.345000 string=yo
    Now we only need to declare the "needed" signature "s.", for printf(char *msg, ...), because we can figure out the rest dynamically, based on getType(args[ii]).

    Limitation:

    We can't use %c (1 byte char) or %g (8 bytes double) without explicit signature, because these types don't exist in CoDScript itself, so there is no way to tell binarybuffer_write() about the type-information only with getType().

    For that case, you need to make the signature explicit:

    PHP Code:
    call_function(libc_printf"s.ifsdc""hi!!! int=%d float=%f string=%s double=%g char=%c\n"1230.345"yo"0.123"#"); 
    Output:
    Code:
    hi!!! int=123 float=0.345000 string=yo double=0.123 char=#
    Return values:

    Just added this in new commit: https://github.com/kungfooman/libcod...dff68c1ba77ba7
    Binaries are updated: http://killtube.org/downloads/libcod/2015.01.17/

    PHP Code:
        ret call_function(libc_printf"s.""asd\n");
        
    printf("printed chars: %\n"ret); 
    Output:
    Code:
    asd
    printed chars: 4
    Basically that's just eax as int though atm. Some converting based on signature would be nice, like "s.)i" for "return an int".
    Last edited by kung foo man; 17th January 2015 at 18:34. Reason: Add limitation info and update call_function to support explicit signature for doubles/chars
    timescale 0.01

  4. The Following 2 Users Say Thank You to kung foo man For This Useful Post:

    php (17th January 2015),voron00 (18th January 2015)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •