Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Callout on CALL instruction are not emitted #806

Closed
hillelpinto opened this issue Jun 24, 2024 · 4 comments
Closed

Callout on CALL instruction are not emitted #806

hillelpinto opened this issue Jun 24, 2024 · 4 comments

Comments

@hillelpinto
Copy link
Contributor

hillelpinto commented Jun 24, 2024

@oleavr

When stalking a thread, i want to emit a callout on every call using cmodule but the callout is never called
In the following picture we can see that we entered the if condition in the transform callback but the callout is never called...

image


To reproduce the issue, use the following code:

var module = Process.enumerateModules()[0]
var mem = Memory.alloc(16);
var appStart = parseInt(module.base, 16);
var ptrToAppStart = mem.writeU64(appStart);
var mem2 = Memory.alloc(16);
var appEnd = appStart + parseInt(module.size,10);
var ptrToAppEnd = mem2.writeU64(appEnd);

const cm = new CModule(`
#include <gum/gumstalker.h>
#include <gum/gummemory.h>
#include <capstone.h>
extern void logging (gchar *message);
extern guint64 *ptrToAppStart ;
extern guint64 *ptrToAppEnd ;
static void log (const gchar * format,...)
{
gchar * message;
va_list args;

va_start (args, format);
message = g_strdup_vprintf (format, args);
va_end (args);

logging(message);

g_free (message);

}

static void on_cmp_wrapper(GumCpuContext * cpu_context, gpointer user_data) {
cs_insn * insn = (cs_insn *)user_data;
log("Got as instruction ID: %d", insn->id);
}

void transform (GumStalkerIterator * iterator,
GumStalkerOutput * output,
gpointer user_data)
{

cs_insn * insn;

while (gum_stalker_iterator_next (iterator, &insn))
{

  gum_stalker_iterator_keep (iterator);
 if (insn->id == X86_INS_CALL && (gpointer)insn->address > ptrToAppStart && (gpointer)insn->address < ptrToAppEnd)
 {
    log("Entered to emit the callout for CALL instructions");
      gum_stalker_iterator_put_callout (iterator,
       on_cmp_wrapper, insn, NULL);

 }

}
}

`,
{
ptrToAppStart, ptrToAppEnd,
logging: new NativeCallback((msg) => {
console.log(msg.readCString());
}, 'void', ['pointer'])

}
);

Stalker.follow(
Process.enumerateThreads()[0].id,
{
transform: cm.transform
}
);

The helloworld.exe targeted can be found here:
helloworld.zip

Same issue if we set the if condition to match each RET instructions

@oleavr
Copy link
Member

oleavr commented Jun 24, 2024

Move the keep() call after the callout. Code emitted after a branch isn't reached, as execution is transferred to the next block.

@oleavr oleavr closed this as completed Jun 24, 2024
@hillelpinto
Copy link
Contributor Author

hillelpinto commented Jun 24, 2024

@oleavr
As you said, I've changed the code like this and this causes the target process to crash and nothing is printed is frida CLI:
image

I also tried to keep the first keep() and just add a second keep() after the callout and still the callout is not called but some log are printed in frida cli but it also trigger the target process to crash
image

@oleavr
Copy link
Member

oleavr commented Jun 24, 2024

I didn't mean to move it inside the if-block. That crashes because you're telling Stalker to skip all instructions except CALL instructions.

Code you emit before keep() is inserted before the instruction being kept, code you emit after gets inserted after the instruction being kept.

@hillelpinto
Copy link
Contributor Author

right, i fixed it like this

image

thx a lot !

the issue #805 still remains though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants