首页
社区
课程
招聘
[求助]请求写2行delphi版的debug api代码
发表于: 2008-1-10 17:33 8656

[求助]请求写2行delphi版的debug api代码

2008-1-10 17:33
8656

目标程序:client.exe
目标地址:004f9000[je换jmp]
写CreateProcess与WriteProcessMemory这2行,delphi版的。
另外有修改寄存器标志位的代码有现成的就贴出个,delphi版的,没有就不麻烦了。

OpenProcessMemory被封,于是寻找新办法,找了8个月,就发现比较完整的c版debug api代码http://blog.csdn.net/red_angelx/archive/2007/01/14/1482924.aspx
依旧没发现delphi版的,或许自己看不懂


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (14)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
Delphi的Debug调试程序?我已经完整写出来了。其实没什么,无非就是API的使用而已。
程序比较大。需要的话等我出差回来给你发一个完整版本。现在给你贴其中一段函数吧。

这个函数是以Debug方式调用exe的示范程序代码,具体知识和内容请查阅相关内容。

procedure TForm1.StartRun;
var
  StartupInfo:TStartupInfo;
  DebugInfo:TDebugEvent;
  iThreadCount:Integer;
begin
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  with StartupInfo do
  begin
    cb := SizeOf(TStartupInfo);
    dwFlags := STARTF_USESHOWWINDOW;
    wShowWindow := SW_NORMAL;
  end;

  if not CreateProcess(nil, PChar(sExe), nil, nil, False,
                       DEBUG_ONLY_THIS_PROCESS, nil,
                       nil, StartupInfo, pi) then
     RaiseLastError;
     
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);
  DebugProcess:=pi.hProcess;
  HideDebug(pi);
  iThreadCount:=0;
  while WaitForDebugEvent(DebugInfo,INFINITE) do
  begin
    case DebugInfo.dwDebugEventCode of
      CREATE_PROCESS_DEBUG_EVENT:
        lstMsg.ItemIndex:=lstMsg.Items.Add('程序开始运行...');
      CREATE_THREAD_DEBUG_EVENT:
      begin
        iThreadCount:=iThreadCount+1;
        lblDebugMsg.Caption:='线程计数:'+IntToStr(iThreadCount);
      end;
      EXIT_PROCESS_DEBUG_EVENT:
      begin
        lstMsg.ItemIndex:=lstMsg.Items.Add('程序退出...');
        bCreate:=False;
        Break;
      end;
      EXCEPTION_ACCESS_VIOLATION:
      begin
        lstMsg.ItemIndex:=lstMsg.Items.Add('读写地址出错:'+
             Format('%d,  %x',[DebugInfo.Exception.ExceptionRecord.ExceptionInformation[0],
                            DebugInfo.Exception.ExceptionRecord.ExceptionAddress]));
        ContinueDebugEvent(DebugInfo.dwProcessId,DebugInfo.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);
        Break;
      end;
      EXCEPTION_DEBUG_EVENT:
        if not OnDebug_Except(DebugInfo) then
        begin
          ContinueDebugEvent(DebugInfo.dwProcessId,DebugInfo.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);
          Break;
        end;
      LOAD_DLL_DEBUG_EVENT:
      begin
        if (not bINT13) and (Trim(lbledtSetPoint.Text)<>EmptyStr) then
//        begin
//          if IsUnpacked(pi) then
              SetBreakPoint(pi,StrToIntDef('$'+Trim(lbledtSetPoint.Text),0));
//        end;
      end;
    end;
    ContinueDebugEvent(DebugInfo.dwProcessId,DebugInfo.dwThreadId,DBG_CONTINUE);
  end;
  lstMsg.ItemIndex:=lstMsg.Items.Add('程序已关闭...');
end;

设置断点的函数:

function TForm1.SetBreakPoint(pi: TProcessInformation; BreakPoint: Cardinal):
    Boolean;
var
  dwRead, OldProtect: Cardinal;
  bRet:Boolean;
  NumberBytes : Cardinal;
const
  INT3:Byte=$cc;
begin
  if BreakPoint=0 then Exit;
  SuspendThread(pi.hThread);
  VirtualProtectEx(pi.hProcess,Pointer(BreakPoint),1,PAGE_READWRITE, OldProtect);
  ReadProcessMemory(pi.hProcess,Pointer(BreakPoint),Pointer(@SourceValue),sizeof(Byte),NumberBytes);
  Result:=WriteProcessMemory(pi.hProcess,Pointer(BreakPoint),@INT3,sizeof(INT3),NumberBytes);
  VirtualProtectEx(pi.hProcess,Pointer(BreakPoint),1,OldProtect,OldProtect);
  iBreakPoint:=BreakPoint;
  bINT13:=True;
  ResumeThread(pi.hThread);
end;
2008-1-11 05:06
0
雪    币: 266
活跃值: (60)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
3
顶,占位中。。
2008-1-11 08:39
0
雪    币: 22
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
2楼第一贴就回复我。呵。激动,代码找的我实在辛苦。详细的等你来家
E-mail:gamecrackers@hotmail.com

修改寄存器的数据,必须是在程序运行到目标地址,加个断点吧,那看来我得换新办法,一段就死。
这代码用来防止内存效应,呵呵
2008-1-11 23:13
0
雪    币: 1312
活跃值: (5164)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
2008-1-13 17:51
0
雪    币: 229
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
不是很清楚的说
2008-1-16 14:03
0
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
7
收藏代码!
期待早日出差出回来
2008-1-17 09:02
0
雪    币: 142
活跃值: (121)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
代码收藏,期待高手回家。。。
2008-1-22 13:42
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
既然懂delphi为什么还要求人呢?网上是有源的.
2008-1-24 14:12
0
雪    币: 178
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
许胜啊。。你去问bill吧。他的stopper for QQT2.0就是基于debug api的。不过新版本无法用debugapi
delphi版的debug api,最好的参考程序就是cheat engine source
2008-2-17 12:08
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
不好意思。到现在才回复...本着代码共享的目的。我给出其他几个函数。

注:但现在的代码只是实现了在指定断点中断。没有实现单步跟踪,我自己没有写完,也不打算实现了,请自行根据现有代码结构,查询相关资料来实现。
PS:给出全部代码我觉得不好,如果只是全部照搬。那也违背了我贴代码的意义:-)

在中断之后,查看寄存器的函数
procedure TForm1.ShowPoint;
var
   Context:TContext;
   NumberBytes, OldProtect:Cardinal;
   sValue:array[1..256] of char;
begin
  lstMsg.ItemIndex:=lstMsg.Items.Add('===========================================');
  SuspendThread(pi.hThread);
  FillChar(Context,SizeOf(TContext),0);
  Context.ContextFlags := CONTEXT_FULL or CONTEXT_DEBUG_REGISTERS;
  GetThreadContext(pi.hThread,Context);
  lbledtEAX.Text:=Format('%x',[Context.Eax]);
  lbledtEsi.Text:=Format('%x',[Context.Esi]);
  lbledtEBP.Text:=Format('%x',[Context.Ebp]);
  lbledtEIP.Text:=Format('%x',[Context.Eip]);
  lbledtESP.Text:=Format('%x',[Context.Esp]);
  if Context.Eip=iBreakPoint+1 then
  begin
    if not CleanBreakPoint(pi,iBreakPoint,SourceValue) then
       raise Exception.Create('清除断点失败!');
    lstMsg.ItemIndex:=lstMsg.Items.Add('程序已经在断点停止');
    VirtualProtectEx(pi.hProcess,Pointer(iBreakPoint),1,PAGE_READWRITE,OldProtect);
    ReadProcessMemory(pi.hProcess,Pointer(Context.Edx),Pointer(@sValue[1]),sizeof(sValue),NumberBytes);
    VirtualProtectEx(pi.hProcess,Pointer(iBreakPoint),1,OldProtect,OldProtect);
    lstMsg.ItemIndex:=lstMsg.Items.Add(Format('%P的内容:%s',[Pointer(iBreakPoint),Trim(sValue)]))
  end;
  lstMsg.ItemIndex:=lstMsg.Items.Add('===========================================');
//  ResumeThread(pi.hThread);
end;

隐含Debug(不适用于所有情况,只是修改Debug标志位来欺骗软件对于Debug的检测)
procedure TForm1.HideDebug(pi: TProcessInformation);
Const
  isDebugFlag:Byte =$00;
  isHeapFlag:Integer =2;
var
  Context:TContext;
  NumberBytes:Cardinal;
  HeapAddress:Cardinal;
begin
  SuspendThread(pi.hThread);
  FillChar(Context, SizeOf(TContext), 0);
  Context.ContextFlags := CONTEXT_FULL or CONTEXT_DEBUG_REGISTERS;
  GetThreadContext(pi.hThread,Context);
  //IsDebugPresent_Flag
  WriteProcessMemory(pi.hProcess,Pointer(Context.Ebx+$2),@isDebugFlag,1,NumberBytes);
  //NTGlobal_Flag  用0D则为70  这个为0 防止其他调试器存在
  WriteProcessMemory(pi.hProcess,Pointer(Context.Ebx+$68),@isDebugFlag,1,NumberBytes);
  //GetProcessHeap_Flag
  ReadProcessMemory(pi.hProcess,Pointer(Context.Ebx + $18),@HeapAddress,sizeof(HeapAddress),NumberBytes);
  WriteProcessMemory(pi.hProcess,Pointer(HeapAddress),@isDebugFlag,sizeof(isDebugFlag),NumberBytes);

  ReadProcessMemory(pi.hProcess,Pointer(Context.Ebx + $68),@isDebugFlag,1,NumberBytes);
  ResumeThread(pi.hThread);
end;

清除断点
function TForm1.CleanBreakPoint(pi: TProcessInformation; BreakPoint: Cardinal;
    OldValue: Byte): Boolean;
var
  NumberBytes:Cardinal;
  context:TContext;
begin
  if bINT13 then
  begin
    Result:=WriteProcessMemory(pi.hProcess,Pointer(BreakPoint),@OldValue,
                               sizeof(Byte),NumberBytes);
    if not Result then
      raise Exception.Create('清除断点失败!');

    bINT13:=False;
    iBreakPoint:=0;
  end;
  Result:=True;
end;
2008-2-19 12:55
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
还有两个函数就不贴了。一个是非常非常简陋的解壳函数。
一个是调用DLL时取出所调用的dll文件名。

在看雪高手如云的情况下。我不太好意思献丑了。
2008-2-19 13:05
0
雪    币: 205
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
太厉害了,向你学习。
2008-2-20 20:03
0
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
14
学习....
要害....
2008-3-1 08:38
0
雪    币: 301
活跃值: (300)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
15
收藏学习备用
2008-3-1 21:25
0
游客
登录 | 注册 方可回帖
返回
//