专栏名称: 看雪学苑
致力于移动与安全研究的开发者社区,看雪学院(kanxue.com)官方微信公众帐号。
目录
相关文章推荐
吾爱破解论坛  ·  分享图片 ·  3 天前  
衡水交通广播  ·  又来了!地磁暴预警! ·  23 小时前  
衡水交通广播  ·  又来了!地磁暴预警! ·  23 小时前  
文明内蒙古  ·  严正声明! ·  昨天  
文明内蒙古  ·  严正声明! ·  昨天  
51好读  ›  专栏  ›  看雪学苑

调试器开发技术-Linux调试器与Windows调试器实现细节探究

看雪学苑  · 公众号  · 互联网安全  · 2025-05-26 17:58

正文

请到「今天看啥」查看全文



1.断点命中

2.设置全局断步标志

3.恢复断点处的原始字节码

4.设置单步

5.单步中读取全局断步标志

6.标志如果命中则需要将 eip-1 (因为这里的 INT3 指令是一个字节)使其eip回到指令该指令之前。

7.重新设置回断点在被单步的地方。

伪代码示例:


bool g_stepSingle = false;
DWORD g_dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;


void HandleSingleStep(Regs& reg)
{    
// 获取寄存器
    CONTEXT Ctx;
if (GetRegs(&Ctx) 0)
return -1;
//...
if (g_stepSingle)
    {
// 重新设置断点
        SetBreakPoint(Ctx.Eip + 1);
        g_dwContinueStatus  = DBG_CONTINUE;
    }
//...
}

void HandleDbg()
{
//... 这里需要做一些判断比如是否为自己的断点
// 获取寄存器
    CONTEXT Ctx;
if (GetRegs(&Ctx) 0)
return;
if (IsMyBreak(Ctx.Eip))
    {
        ReserveBreakPoint(Ctx.Eip);
        g_stepSingle = true;
        Ctx.Eip -= 1;
// 跳到单步
        SetSingleStep();
         g_dwContinueStatus  = DBG_CONTINUE;
    }
}


而在Linux情况下我们一般如下进行处理


longWaitProcess(){
long result = waitpid(env.pid, nullptr, WNOHANG);

if (result == -1)
    {
printf("waitpid err: %s",strerror(errno));
return result;
    }

if (result == 0)
    {
return result;
    }

// 目标进程来了
siginfo_t si{};
    result = ptrace(PTRACE_GETSIGINFO, env.pid, nullptr, &si);
if (result == -1)
    {
printf("ptrace PTRACE_GETSIGINFO err: %s",strerror(errno));
return result;
    }

/*
    如果断点来了可以通过sig_signo 大致做出区分其中,sig_code 做出细分即可
    */
// printf("signo:%d, errno:%d, sigcode:%d\n", si.si_signo, si.si_errno, si.si_code);
    user_regs_struct reg{};

/* DOR 调用 */
    CCmdReg* pReg = (CCmdReg*)g_cmd[(int)DOR_IDX::EnumCmdReg];
    CCmdBp* pBp = (CCmdBp*)g_cmd[(int)DOR_IDX::EnumCmdBp];
    CCmdStepInto* pStepIn = (CCmdStepInto*)g_cmd[(int)DOR_IDX::EnumStepInto];
    CCmdMem* pMem = (CCmdMem*)g_cmd[(int)DOR_IDX::EnumCmdMem];
/* 读寄存器 */
    pReg->ReadReg(®);
    env.tag_currentAddress = reg.pc;
    env.tag_disasmAddress = reg.pc;


uint8_t insn[12]{0};

/* 断步配合 */
if (env.tag_stepBpFlag)
    {
        pBp->SetBp(env.tag_stepBpReverseAddr);
/* 重置断步配合标志 */
        env.tag_stepBpReverseAddr = 0;
        env.tag_stepBpFlag = false;
    }

if (env.tag_resumeFlag)
    {
        env.tag_resumeFlag = false;
        CCmdResume* pResume = (CCmdResume*)g_cmd[(int)DOR_IDX::EnumCmdResume];
        pResume ->Resume();
return result;
    }


switch(si.si_signo)
    {
case SIGSTOP:
        {
printf("\nprocess stop.\n");
break;
        }
case SIGTRAP:
        {
switch (si.si_code) {
case TRAP_BRKPT:
                {

                    pReg->ShowReg(®);
if (env.tag_stepOverFlag)
                    {
                        pMem->WriteMem(env.tag_currentAddress, env.tag_stepOverBuffer, 4);
                        env.tag_stepOverFlag = false;
                    }

if (env.tag_stepBpResFlag)
                    {
                        pBp->SetBp(env.tag_stepBpResAddr);
                        env.tag_stepBpResFlag = false;
                        env.tag_stepBpResAddr = 0;
                    }

if (pBp->IsBpExist(reg.pc))
                    {
printf("\nHit bp! at 0x%lx\n", reg.pc);

//pMem->WriteMem(env.tag_currentAddress, env.tag_stepOverBuffer, 4);
                        pBp->ReserveMem(reg.pc);

                        env.tag_stepBpReverseAddr = reg.pc;
                        env.tag_stepBpFlag = true;

// pStepIn->SetSingleStep();
                    }
//}

                    pMem->ReadMem(reg.pc, insn, 12);
for (int i = 0; i 3; i++)
                    {
                        env.disasm.Disasm(reg.pc + i * 4, insn + i * 44);
                    }

break;
                }
case TRAP_TRACE:
                {
if (env.tag_stepBpResFlag)
                    {
                        pBp->SetBp(env.tag_stepBpResAddr);
                        env.tag_stepBpResFlag = false;
                        env.tag_stepBpResAddr = 0;
                    }

if (env.tag_traceFlag)
                    {
if (reg.pc == env.tag_traceTargetAddr)
                        {
                            env.tag_traceTargetAddr = 0;
                            env.tag_traceFlag = false;

                        }
else
                        {
                            pMem->ReadMem(reg.pc, insn, 12);
for (int i = 0; i 1; i++) {
                                env.disasm.Disasm(reg.pc + i * 4, insn + i * 44);
                            }
                            pStepIn->SetSingleStep();
break;
                        }
                    }


                    pReg->ShowReg(®);
                    pMem->ReadMem(reg.pc, insn, 12);
for (int i = 0; i 3; i++)
                    {
                        env.disasm.Disasm(reg.pc + i * 4, insn + i * 44);
                    }
break;
                }
            }






请到「今天看啥」查看全文


推荐文章
吾爱破解论坛  ·  分享图片
3 天前
衡水交通广播  ·  又来了!地磁暴预警!
23 小时前
衡水交通广播  ·  又来了!地磁暴预警!
23 小时前
文明内蒙古  ·  严正声明!
昨天
文明内蒙古  ·  严正声明!
昨天
一条  ·  我就爱拍色情和暴力
8 年前
肌肉男训练营  ·  关于蛋白质补充,你必须知道的真相!
8 年前