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

Hook 后 onCallBack 收到的参数数据不正确 #14

Open
xiaoxiayu opened this issue Jul 11, 2019 · 2 comments
Open

Hook 后 onCallBack 收到的参数数据不正确 #14

xiaoxiayu opened this issue Jul 11, 2019 · 2 comments

Comments

@xiaoxiayu
Copy link

使用 armHook 后,可以跳转到 onCallBack 的函数去,但是 onCallBack 参数收到的参数不正确。

使用方式是直接参考的 Demo 里的 bool InlineHook(void *pHookAddr, void (*onCallBack)(struct pt_regs *)), 只修改了 onCallBack,改成适合自己的格式。


// 头文件
typedef struct tagINLINEHOOKINFO{
    void *pHookAddr;
    void *pStubShellCodeAddr;  
    void*(*onCallBack)(void*, void*, void*); // onCallBack 改了下,和demo 里有点区别
    void ** ppOldFuncAddr;
    BYTE szbyBackupOpcodes[OPCODEMAXLEN]; 
    int backUpLength;
    int backUpFixLengthList[BACKUP_CODE_NUM_MAX]; 
    uint32_t *pNewEntryForOldFunction;
} INLINE_HOOK_INFO;

// Hook 实现
bool TestHooker::Hook(const char* name, void* org,  void*(*dest)(void*, void*, void*)) {
    bool bRet = false;

    if(org == NULL || dest == NULL)
    {
        return bRet;
    }

    INLINE_HOOK_INFO* pstInlineHook = new INLINE_HOOK_INFO();
    pstInlineHook->pHookAddr = org;
    pstInlineHook->onCallBack = dest;

    if(TEST_BIT0((uint32_t)pstInlineHook->pHookAddr)) { 
        if(HookThumb(pstInlineHook) == false) {
            delete pstInlineHook;
            return bRet;
        }
    } else {
        if(HookArm(pstInlineHook) == false) { // 使用的是 HookArm
            delete pstInlineHook;
            return bRet;
        }
    }
    m_InlineHookInfoPVec.push_back(pstInlineHook);
    Origin_getenv = *pstInlineHook->ppOldFuncAddr;
    return true;
}
// OnCallback 函数
void* CalledFunc(void* param0, void* param1, void* param2){
    std::string memStr = PrintBuffer(param0, 10);
     __android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "** %s **", memStr.c_str()); // **被调用后,打印出 ”50 30 02 e4 00 00 00 00 00 00“,内容是不正确的。**
    return ((void*(*)(void*, void*, void*))Origin_getenv)(param0, param1, param2);;
}

// 运行
Hook("test",  orgAddr, CalledFunc); // orgAddr 是从一个第三方 so 中获取出的函数地址。

Hook 运行后正确执行到了 CalledFunc, Orgigin_getenv 调用也正确,但参数的数据都不对了
有试过对同一个 so 的另一个只有一个参数的函数 hook过,运行是正常的。
测试机: Google Pixel2

刚接触 hook ,对 arm 和底层不大了解,哪位大佬能帮忙看下问题大概是出在哪里吗。

@strawmanbobi
Copy link

strawmanbobi commented Jul 24, 2019

arm 的参数传递是用寄存器 R0-R3 传递前 4 个参数,多余的就用栈。
在这个项目里,你看下 shell code,它最后跳转到你定义的 stub function 时会把 sp 放到 R0 里传给你,所以你只能通过 ptrace 的结构体去获取参数,如果想从函数原型中取得参数,把 shell code 里最后 mov r0, sp 去掉。

@strawmanbobi
Copy link

其实我也比较好奇说这个 shell code 为了保护 R0-R12 ,用到了 sp,那么栈实际上是被破坏掉了,应该看不到第 4 个参数之后的参数才对,不知道作者怎么看?(当然在 stub call 结束之后 sp 是被还原了,所以跳回到 original function 的时候参数都还正确)

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