richard_ljd 发表于 2024-4-28 16:26

初学,关于异常处理的一个问题

我在通过视频学习的过程中,视频讲到了关于程序异常中断的内容。我对这部分内容产生了一些思考,如果可以通过引发中断(int 3),来调用我自己设置的异常处理函数的话,我是不是可以做到一个简单的反调试?然后我进行了尝试
我的思路是:程序主动引发异常---->异常处理函数将异常部分nop掉--->程序正常运行
下面是代码
#include <iostream>
#include <Windows.h>

HMODULE baseAddress = 0;

LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS pExceptionInfo)
{
        std::cout << "Eip:" << pExceptionInfo->ContextRecord->Eip << std::endl;    //输出当前的Eip


                uintptr_t offset = 0x125EA;   
                uintptr_t targetAddress = reinterpret_cast<uintptr_t>(baseAddress) + offset;   
//offset的偏移值是我经过几次调试确定的准确位置,这里没有问题,targetAddress是进行计算的。最开始是直接用baseAddress +=0x125EA结果计算一直有错误,就改成这样了。

        byte replacementByte = 0x90; // NOP,替换的指令

        std::cout << "(LPVOID)targetAddress:" << (LPVOID)targetAddress <<std::endl;                   //检验目标地址类型转换结果是否有问题
        std::cout << " (LPCVOID)replacementByte:"<< (LPCVOID)replacementByte <<std::endl;    //检验要替换的指令类型转换是否有问题
       
       
        BOOL success = WriteProcessMemory(GetCurrentProcess(), (LPVOID)targetAddress,(LPCVOID)replacementByte,1,NULL);   //将指令写入
        if (!success)   //检查是否写入成功
                std::cout << "success为0,写入失败"<< std::endl;   


        return EXCEPTION_EXECUTE_HANDLER;
}


int main(int argc, char const *argv[])
{
        baseAddress = GetModuleHandle(NULL);   //获取程序基址

        AddVectoredContinueHandler(NULL, VectoredHandler);   //添加异常处理

        _asm {    //异常代码
                int 3;
        }

        std::cout << "Hello world!" << std::endl;   //如果异常解决后会执行的代码

        system("pause");
        return 0;
}



按照设想当程序运行到int 3的时候引发异常,然后调用我写好的处理函数,将int3 替换成nop随后回到异常位置向下运行,经过了nop执行Hello world

但是实际的情况比较头疼,直接运行引发系统提示中断,然后我取消调试就是如下结果(win10系统下直接运行):


直接运行存在问题,那么我去用dbg运行看看是否修改(win10系统dbg调试运行)

尽管函数的返回值告诉我已经替换成功但依旧没有替换。

想要问一下这是什么情况 ?

bester 发表于 2024-4-28 18:15

WriteProcessMemory 第三个参数没取地址

另外提两点,你这里用指针操作比用api方便,

你用api 也不获取一下内存权限,看是否可读可写

richard_ljd 发表于 2024-4-28 18:53

bester 发表于 2024-4-28 18:15
WriteProcessMemory 第三个参数没取地址

另外提两点,你这里用指针操作比用api方便,


更改了以后成功了(感动人心),当时我在翻文档的时候看到GetCurrenProcess里面说"此句柄具有 对 进程对象的PROCESS_ALL_ACCESS访问权限"就直接使用了,忘记这个还需要用OpenProcess获得进程句柄。
修改后改成了WriteProcessMemory(OpenProcess(PROCESS_ALL_ACCESS,true, GetCurrentProcessId()), (LPVOID)targetAddress,&replacementByte,1,NULL);
代码更改以后上面的偏移值也重新看了一下,改成了新值(未来或许有更好的办法,但是现在暂时先这样用着吧...)
然后运行结果如下

随后中断触发,进入我的异常处理函数

成功修改,终于结束了(喜)
用指针直接操作下去我试试,虽然C也用了不少时间了,但是指针一般不敢怎么玩,所以不太了解怎么操作。
感谢
页: [1]
查看完整版本: 初学,关于异常处理的一个问题