Android自修改代码-NDK

Android自修改代码-NDK,android,android-ndk,self-modifying,Android,Android Ndk,Self Modifying,我正在尝试制作一个自我修改的代码库,我已经仔细研究过了,我得到了以下代码: typedef int (*FUNC) (void); int test(); JNIEXPORT int Java_com_example_untitled_MyActivity_decrypt( JNIEnv* env, jobject thiz) { void *code = mmap(NULL, 4, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS

我正在尝试制作一个自我修改的代码库,我已经仔细研究过了,我得到了以下代码:

typedef int (*FUNC) (void);
int test();

JNIEXPORT int Java_com_example_untitled_MyActivity_decrypt( JNIEnv* env, jobject thiz)
{
    void *code = mmap(NULL, 4, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

    if (code != MAP_FAILED) {
        memcpy(code, test, 4);

        return ( (FUNC)code)();
    }

    return 0;
}

int test()
{
    return 100;
}
请帮助我…我把它作为我的出发点,他们说了一些关于用“-marm”和拇指位编译的事情


我的问题是,它只是崩溃了。我尝试过使用cacheflush函数,但似乎没有帮助。我不知所措。

在ARM上,您需要刷新CPU缓存,以确保刚刚复制的指令在执行之前对CPU可见。一个简单的方法是:

#include <unistd.h>  // for cacheflush()

...

// Copy the instructions to the destination address.
memcpy(dest, original_intructions, size_of_instructions);

// Clear the CPU cache
cacheflush((uintptr_t)dest, (uintptr_t)dest + size_of_instructions, 0);

// Run them.
return ((FUNC)dest)();
#包括//用于cacheflush()
...
//将说明复制到目标地址。
memcpy(目的地、原始指令、指令大小);
//清除CPU缓存
cacheflush((uintptr\u t)dest,(uintpttr\u t)dest+u指令的大小,0);
//运行它们。
返回((FUNC)dest)();

您遇到了什么问题?代码的预期行为和观察到的行为是什么?(例如,为什么您认为测试正好是4字节长?)因为我对ARM进行了反向工程,知道mov R0100是2字节,BX LR是2字节…:)还验证了它没有使用4字节mov指令。ARM指令的长度是4字节…不,不总是这样。我向IDA查询,每条指令只有2个字节。我对Android游戏进行了逆向工程,在ARM中修改了100多个游戏,使用2字节和4字节指令。对我来说,听起来像是拇指,而不是ARM。要从Thumb调用ARM或从ARM调用Thumb,需要进行指令集交换(BLX而不是BL)。双字节BX LR指令是从thumb代码返回到ARM的指令;但是打电话的人需要知道如何改变通话模式(或者只是简单地使用ARM),这不是直接的问题。这个问题正如addaon所说的那样。也许你可以回答我这个问题,我可以编译一个函数,使用ARM,删除函数,然后仍然使用ARM并向它传递参数吗?或者ARM是否使用会导致问题的内存地址?这取决于函数的编译方式。您需要首先使用-fPIC来生成与位置无关的代码。其次,您需要确保该函数从不尝试访问全局变量或其他函数(这两种函数都会引入重定位,从而阻止执行您想要的操作)。我最终只是使用mprotect修改了应用程序的内存,因此代码只是在ida中使用AES和多级模糊处理进行模糊处理。