Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>Was just thinking that if I can turn somthing into a jmp somehow then I can put my code somewhere else, do whatever I overwrote and jump back to the next instruction after? </p> </blockquote> <p>...this is a good approach for patching code at run-time, yes. But there may be fiddly details to consider depending on exactly what the instructions that are overwritten do. And code injection may be harder than you expect anyway: for example, the code may well be mapped read-only.</p> <blockquote> <p>the entire code for this is very very long since it is very generall being able to call any function with upto 16 arguments plus relevant memory management for strings, and supporting either __stdcall or __cdecl)</p> </blockquote> <p>So: this code calls back into your code, and can pass arguments? Can you register at least one pointer-sized argument along with the function that will be called back?</p> <p>If so, you can pass the <code>this</code> pointer yourself, with a bit of fiddling. You will need to register a function that does <em>not</em> require a <code>this</code> pointer (such as a static member function) as the callback, along with the <code>this</code> pointer as an argument for the callback; that callback can then unwrap the argument in order to call the member function that you really want to call.</p> <p>Something like this (with apologies if it's obvious that I spend most of my life writing C rather than C++):</p> <pre><code>#include &lt;iostream&gt; // Simple C callback interface extern "C" { typedef void (*tCallbackFn)(void *); static struct { tCallbackFn fn; void *context; } callback; static void set_callback(tCallbackFn fn, void *context) { callback.fn = fn; callback.context = context; } static void call_callback(void) { (callback.fn)(callback.context); } } // Simple test class class MyClass { public: // We'll use this for test purposes int id; // This is the actual member function we want to invoke void DoIt(void) { std::cout &lt;&lt; "Callback - id = " &lt;&lt; id &lt;&lt; std::endl; } // Static wrapper which we can pass as the function in the callback interface static void CallbackWrapper(void *context) { static_cast&lt;MyClass *&gt;(context)-&gt;DoIt(); } // Register wrapper as callback function, with "this" pointer as context void Test(void) { set_callback(CallbackWrapper, static_cast&lt;void *&gt;(this)); call_callback(); } }; // Test it int main(void) { MyClass m1, m2; m1.id = 1; m2.id = 2; m1.Test(); m2.Test(); return 0; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. COUnfortunatly for whatever reason within there scripting environment they choose to use id numbers rather than real pointer values, and then as part of the calling procedure from the script into there API's (such as the one I had the code listing for) they lookup the pointer value. This appears to be a table, however they provided no API for me to get the address of this table, and with new builds coming out every few days, I suspect it is liable to change (as I said the procedure address is povided by a documented API, as is the procedure to call into external native code)
      singulars
    2. COI managed to make some progress on code injection, use the VirtualProject win32 api to get write access. Allthough I hit an interting problem that apperently 00613ED4 is a read only byte of some sort. I actually tried essentially "mov dword ptr [00613ED4], 11223344h" and it wrote the next 3 bytes, but left 00613ED4 alone :( I assume other platforms have similar systems?
      singulars
    3. COI have no idea what the problem is (I'm no Windows expert), but read/write/execute permissions are properties of a page (for x86) so a "read only byte" in the middle of a page seems unlikely. I don't know whether `VirtualProtect()` is expected to work correctly for manipulating code mappings. (Linux has `mprotect()`, which is a POSIX-specified function that does something similar; Linux does allow it to be used for changing code mappings, but that is functionality that Linux provides beyond the requirements of the POSIX spec, which only guarantees it will work for areas returned by `mmap()`.)
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload