反调试-----由IsDebuggerPresent函数看下去
来源:互联网 发布:什么时候出5g网络 编辑:程序博客网 时间:2024/05/24 16:15
通过已知的函数研究反调试也许能学到些东西,先示例下简单的函数IsDebuggerPresent ?
if(IsDebuggerPresent())
{
cout<<"this process is debugging"<<endl;
}else
{
cout<<"this process is run normal"<<endl;
}
在OD下看看IsDebuggerPresent的实现:
7600377C > 64:A1 18000000 MOV EAX,DWORD PTR FS:[18]
76003782 8B40 30 MOV EAX,DWORD PTR DS:[EAX+30]
76003785 0FB640 02 MOVZX EAX,BYTE PTR DS:[EAX+2]
mov eax,dword ptr fs:[18] ?fs:[18]是什么?网搜一下,发现是TIB(Win 32 Thread Information Block)或TEB存贮的指向自身的线性指针(地址),详情可以参考:http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
TEB 开始于fs:[0],但是很少通过访问fs:[0]获取TEB的区域,而是通过访问fs:[18]存储的地址。fs:[0x30]存储的是指向PEB的地址。
typedef struct _PEB { BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2[1]; PVOID Reserved3[2]; PPEB_LDR_DATA Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; BYTE Reserved4[104]; PVOID Reserved5[52]; PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; BYTE Reserved6[128]; PVOID Reserved7[1]; ULONG SessionId;} PEB, *PPEB;从PEB的结构可以看出第二个偏移字节为BeingDebugged字段,如果该字段=1表示程序在被调试,反调试的软件可以关闭自身。
————————————————————————————————————————————————————————————————————
突然想继续看看Ldr字段,PPEB_LDR_DATA 的定义:
typedef struct _PEB_LDR_DATA { BYTE Reserved1[8]; PVOID Reserved2[3]; LIST_ENTRY InMemoryOrderModuleList;} PEB_LDR_DATA, *PPEB_LDR_DATA;
而LIST_ENTRY的定义如下:
typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink;} LIST_ENTRY查看MSDN说LIST_ENTRY是个双向链表,且每个项是指向LDR_DATA_TABLE_ENTRY结构的指针,可是LIST_ENTRY中木有data域啊?只有两个指针?what mean?
查看LDR_DATA_TABLE_ENTRY的结构:
typedef struct _LDR_DATA_TABLE_ENTRY { PVOID Reserved1[2]; LIST_ENTRY InMemoryOrderLinks; PVOID Reserved2[2]; PVOID DllBase; PVOID EntryPoint; PVOID Reserved3; UNICODE_STRING FullDllName; BYTE Reserved4[8]; PVOID Reserved5[3]; union { ULONG CheckSum; PVOID Reserved6; }; ULONG TimeDateStamp;} LDR_DATA_TABLE_ENTRYPEB_LDR_DATA中的LIST_ENTRY跟LDR_DATA_TABLE_ENTRY中的LIST_ENTRY组成双向链表?
经过OD和实验分析证明想法是对的.
c代码验证想法:vs2010编译通过
#include <iostream>
#include <tchar.h>
#include <string>
#include <Windows.h>
#include <winternl.h>
using namespace std;
int main()
{
PPEB peb;
if(IsDebuggerPresent())
{
cout<<"this process is debugging"<<endl;
}else
{
cout<<"this process is run normal"<<endl;
}
_asm
{//获取PEB位置
mov eax,FS:[0x18]
mov eax, ds:[eax+0x30]
mov peb,eax
}
cout<<hex<<peb<<endl;
PPEB_LDR_DATA LoaderData=peb->Ldr;
cout<<hex<<LoaderData<<endl;
LIST_ENTRY list_entry_inLDR=LoaderData->InMemoryOrderModuleList;
//PLIST_ENTRY startPointer=list_entry_inLDR.Blink;
PLIST_ENTRY movePointer=list_entry_inLDR.Blink;
do{
//cout<<hex<<"1:"<<movePointer<<endl;
//cout<<sizeof(PVOID)<<endl;
PLDR_DATA_TABLE_ENTRY pLDr_data_table_entry;
_asm
{//将双向链表的指针后移0x8个字节即获得指向LDR_DATA_TABLE_ENTRY的指针
mov eax,movePointer
sub eax,0x8
mov pLDr_data_table_entry,eax
}
cout<<"pLDr_data_table_entry:"<<pLDr_data_table_entry<<endl;
//movePointer=pLDr_data_table_entry->InMemoryOrderLinks.Blink;//A处
cout<<hex<<" || DllBase=0x"<<pLDr_data_table_entry->DllBase <<" |EntryPointer=0x"<<pLDr_data_table_entry->Reserved3[0]<<endl;
std::wcout<<"DllName:"<<(pLDr_data_table_entry->FullDllName).Buffer<<endl;
if(movePointer==list_entry_inLDR.Flink)
break;
movePointer=pLDr_data_table_entry->InMemoryOrderLinks.Blink;// 从A处移至此处主要是为了最后一个模块信息的输出
}while(1);
}
- 反调试-----由IsDebuggerPresent函数看下去
- 反调试 - IsDebuggerPresent
- 1.ring3-反调试-IsDebuggerPresent
- 反调试技术- IsDebuggerPresent,原理 与 反反调试
- isdebuggerpresent
- IsDebuggerPresent() 函数检测进程是否运行在调试器的控制下
- 反汇编调试objc_msgSend函数
- stripslashes() 函数删除由 addslashes() 函数添加的反斜杠
- 《脱壳艺术》学习笔记--IsDebuggerPresent 检测调试器
- 5.windbg script-禁用IsDebuggerPresent(调试 kernel32!SetUnhandledExceptionFilter)
- 函数调试的反汇编分析
- 学习用反汇编调试,看存储单元的变化
- 看雪论坛大神的破解游戏反调试思路
- 反反调试总结
- 反调试
- 从反汇编的角度看C++语法(构造函数)
- 由内存复制函数看assert宏的使用
- 反调试与反反调试
- C#如何使用GetTcpTable API获取TCP/IP连接信息
- 100M和1000M网线做法
- POJ 3438 Look and Say (水题)
- 孖宝英语-视频分享
- VC++ 获取跳转后的url函数实现及相关资料
- 反调试-----由IsDebuggerPresent函数看下去
- iOS KVC 存在的问题
- J.U.C之Atomic&CAS
- The Career Path of a Software Engineer
- Linux内存地址
- CyclicBarrier的介绍和使用
- OCP-1Z0-053-V12.02-446题
- 【OpenCV】数字图像灰度直方图
- ORA-00257: 归档程序错误。在释放之前仅限于内部连接