跳至主要内容

反Hook 之自己实现GetProcAddress和LoadLibraryA(c++ version)

http://ift.tt/2AocAD0
// 课上练习.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
//要实现的功能:
/*
    自己实现GerProcAddress
    LoadLibraryA
*/


//思路:
/*
    GerProcAddress和LoadLibraryA都是在Kernel32.dll中的
    首要的任务就是找到Kernel32.dll,然后遍历IAT就能找到这两个函数
    现在首要的难点就是如何找到kernel32.dll()
    通过dll的加载顺序可以找到,而且虽然需要使用未文档化的API,但是好在windgb可以直接看,而且用到的也并不是很多
    懒得去晚上搜了,直接自己实现一个得了,作为演示,能用就行(最好还是搜一个正规的结构体)
*/

/*
0: kd> dt _TEB /a
nt!_TEB
+0x000 NtTib            : _NT_TIB
+0x01c EnvironmentPointer : Ptr32 Void
+0x020 ClientId         : _CLIENT_ID
+0x028 ActiveRpcHandle  : Ptr32 Void
+0x02c ThreadLocalStoragePointer : Ptr32 Void
+0x030 ProcessEnvironmentBlock : Ptr32 _PEB

//首先实现部分TEB结构体,因为只需要用的PEB的部分,所以实现到这就ok了
*/


//构建 TEB
typedef struct _TEB
{
    //保证0x30是peb的结构体就ok了
    struct _tem
    {
        DWORD a1;
        DWORD a2;
        DWORD a3;
        DWORD a4;
        DWORD a5;
        DWORD a6;
        DWORD a7;
        DWORD a8;
        DWORD a9;
        DWORD a10;
        DWORD a11;
        DWORD a12;
    }tem;
    DWORD _Peb;

}TEB,*PTEB;


//构建 局部 _PEB
/*
    0: kd> dt _PEB /b
    nt!_PEB
    +0x000 InheritedAddressSpace : UChar
    +0x001 ReadImageFileExecOptions : UChar
    +0x002 BeingDebugged    : UChar
    +0x003 BitField         : UChar
    +0x003 ImageUsesLargePages : Pos 0, 1 Bit
    +0x003 IsProtectedProcess : Pos 1, 1 Bit
    +0x003 IsLegacyProcess  : Pos 2, 1 Bit
    +0x003 IsImageDynamicallyRelocated : Pos 3, 1 Bit
    +0x003 SkipPatchingUser32Forwarders : Pos 4, 1 Bit
    +0x003 SpareBits        : Pos 5, 3 Bits
    +0x004 Mutant           : Ptr32
    +0x008 ImageBaseAddress : Ptr32
    +0x00c Ldr              : Ptr32
*/

typedef struct _PEB_LDR_DATA
{
    int Length;
    int Initialized;
    DWORD SsHandle;
    PLIST_ENTRY InLoadOrderModuleList; //只用到这里,所以到这就暂时ok吧
}PEB_LDR_DATA,*PPEB_LDR_DATA;

typedef struct _PEB
{
    DWORD tem1;
    DWORD tem2;
    DWORD tem3;
    PPEB_LDR_DATA Ldr; //需要先实现一个此结构体
}PEB,*PPEB;

typedef struct _LDR_DATA_TABLE_ENTRY
{
    struct InLoadOrderLinks
    {
        PLIST_ENTRY Flink;

        PLIST_ENTRY Blink;
    }InLoadOrderLinks;
    struct InMemoryOrderLinks
    {
        PLIST_ENTRY Flink;

        PLIST_ENTRY Blink;
    }InMemoryOrderLinks;
    struct InInitializationOrderLinks
    {
        PLIST_ENTRY Flink;

        PLIST_ENTRY Blink;
    }InInitializationOrderLinks;

    DWORD DllBase;//加载基址

}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;

//遍历导出表,然后根据函数名称,获取制定的函数地址

PVOID MyGetFnAddress(HMODULE hMoudle, const char * pProcName)
{
    PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMoudle;
    PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(pDosHdr->e_lfanew + (ULONG_PTR)pDosHdr);
    PIMAGE_OPTIONAL_HEADER pOpHdr = (PIMAGE_OPTIONAL_HEADER)&pNtHdr->OptionalHeader;
    //获取到op头之后,就是获取导出表
    PIMAGE_EXPORT_DIRECTORY  pExportDir = (PIMAGE_EXPORT_DIRECTORY)(pOpHdr->DataDirectory[0].VirtualAddress+(ULONG)pDosHdr);


    DWORD *pEnt = (DWORD *)(pExportDir->AddressOfNames + (ULONG_PTR)pDosHdr);
    //然后就开始便利了,首先遍历的是导入名称表
    for (DWORD i =0;i<pExportDir->NumberOfNames;i++)
    {
        char * pEntName = (char*)(pEnt[i] + (ULONG_PTR)pDosHdr);
        if (strcmp(pProcName, pEntName)==0)
        {
            //说明找到了输入的函数名
            //然后去找这个函数名的在导出函数地址表中的地址
            WORD* pEot = (WORD* )(pExportDir->AddressOfNameOrdinals+(ULONG_PTR)pDosHdr);
            DWORD index = pEot[i];
            DWORD * pEat = (DWORD*)(pExportDir->AddressOfFunctions + (ULONG_PTR)pDosHdr);
            DWORD pFnAddress = pEat[index];
            return (PVOID)pFnAddress;
        }
    }
    //没有找到
    return NULL;
}


int main()
{
    
    //获取teb
    PTEB pTeb = NtCurrentTeb();
    //获取peb
    PPEB pPeb= (PPEB)pTeb->_Peb;
    
    //然后是找到ldr
    PPEB_LDR_DATA pLdr = pPeb->Ldr;

    //首先是获取InLoadOrderModuleList 
    PLIST_ENTRY pListEntry = pLdr->InLoadOrderModuleList->Flink;
    
    PLDR_DATA_TABLE_ENTRY pKernel32 = (PLDR_DATA_TABLE_ENTRY)pListEntry->Flink;

    HMODULE hMoudle = (HMODULE)pKernel32->DllBase;
    
    //定义两个函数指针
    /* 
    原型
    WINAPI
GetProcAddress(
    _In_ HMODULE hModule,
    _In_ LPCSTR lpProcName
    );

    HMODULE
    WINAPI
    LoadLibraryA(
    _In_ LPCSTR lpLibFileName
    );
    */
    typedef LPVOID(WINAPI* MYGETPROCADDRESS)(HMODULE hMoudle, LPCSTR lpProcName);
    typedef HMODULE(WINAPI*MYLOADLIBRARYA)(LPCSTR lpLibFileName);
    
    MYGETPROCADDRESS MyGetProcAddress = (MYGETPROCADDRESS)MyGetFnAddress(hMoudle, "GetProcAddress");
    MYLOADLIBRARYA MyLoadLibraryA = (MYLOADLIBRARYA)MyGetFnAddress(hMoudle, "LoadLibraryA");

//这就找到了这个2个api的地址,如果对方进行了自定义hook,这个时候大可以自定去读取OpCode进行判断

// c++ 写的比较麻烦,稍后用汇编写一个,比较简洁易懂


    return 0;
}


The post 反Hook 之自己实现GetProcAddress和LoadLibraryA(c++ version) appeared first on cole.

http://ift.tt/eA8V8J reverse engineering, reverse December 04, 2017 at 07:33PM

评论

此博客中的热门博文

IDA动态调试ELF中遇到的问题(1)

https://ift.tt/2Gxnf2F 遇到 got SIGCHLD singal(child status has changed)...这种提示 singal fork了子进程 直接点yes,然后继续单步执行,出来提示 pass to application就行了 内存查看 用od习惯了之后,凡事都想右键看一下内存,但是IDA中好像没有那么如意, 目前只是在栈中右键发现有查看hex的选项 动态调试的时候的nop ida保存动态调试的时候修改的数据 方法一:在程序运行的时候保存 The post IDA动态调试ELF中遇到的问题(1) appeared first on cole . https://ift.tt/2q9Qf5g WHATEVER April 05, 2018 at 09:44AM

数据库(MySQL)编程之数据库和表的基本操作

http://ift.tt/2gOXg6X     数据库和表的基本操作 操作前的基本知识 基本 sql语句不区分大小写(关键字建议用大小写),但字符串常量区分大小写 sql语句可单行或多行书写,以; 结尾 关键字不能跨行或简写 可以用空格或者缩进来提高可读性 注释 sql标准 /**/ : 多行注释 "--":单行注释 mysql 标准: "#":单行注释 "COMMENT":为字段或列添加注释 创建和查看数据库 创建数据库 模板 CREATE DATABASE [IF NOT EXISTS ] db_name create_specification: IF NOT EXITSTS : 检查数据库是否存在,如果存在就不创建 creat_specification :创建条件 CHARACTER SET: 制定数据聚采用的字符集 COLLATE :制定数据库字符集的比较方式 DEFAULT :表示默认内容,即使没有制定该项,也有默认的值 # 创建数据库使用字符集为 UTF-8 ,使用规则为 uftf_bin CREATE DATABASE db_name DEFAULT CHARACTER SET utf8 COLLATE uft8_bin; 一般默认的数据库就是utf8 和utf8_bin的比较方式,因此一般创建数据库的时候都用 CREATE DATABASE db_name mysql> create database testdb; Query OK, 1 row affected (0.02 sec) 查看数据库 命令 SHOW DATABASES     mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sakila | | sys | | testdb | |...