首页
社区
课程
招聘
[原创][原创]反调试-----由IsDebuggerPresent函数看下去
发表于: 2013-11-8 23:57 11876

[原创][原创]反调试-----由IsDebuggerPresent函数看下去

2013-11-8 23:57
11876

小白自学习,大牛勿拍,谢谢~
通过已知的函数研究反调试也许能学到些东西,先示例下简单的函数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_ENTRY

PEB_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);

}


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

收藏
免费 5
支持
分享
最新回复 (8)
雪    币: 14
活跃值: (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
深奥啊,不过看着学习
2013-11-9 07:21
0
雪    币: 341
活跃值: (143)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
3
好东西。。。了解一下
2013-11-9 09:30
0
雪    币: 116
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
然后你还可以在双向链表中删除指定dll来达到隐藏dll的目的
2013-11-9 19:18
0
雪    币: 124
活跃值: (469)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
这个好东西啊,,,,,,,
2013-11-9 20:59
0
雪    币: 341
活跃值: (85)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
6
论坛很多了
2013-11-10 12:25
0
雪    币: 471
活跃值: (40)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
对哈,一时没想到,谢谢提醒,这个还可以延伸下加点实验试试
2013-11-11 16:59
0
雪    币: 471
活跃值: (40)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
8
主要是自己学点东西,写帖子主要是理理自己的思路,只看不写容易忘~
2013-11-11 17:01
0
雪    币: 1491
活跃值: (985)
能力值: (RANK:860 )
在线值:
发帖
回帖
粉丝
9
文章很不错,很有启发性,谢谢楼主了
2013-11-11 23:31
0
游客
登录 | 注册 方可回帖
返回
//