前言
分析过一些文件,发现里面都会对引用的api进行动态获取,然后通过内存指针调用。细细想来,这种方法还是有一定的对抗作用的,如果别人想要分析的必须的稍微深入或者动态调试一下。然后,我就想着该如何实现这种用法呢?那么多api地址该如何存放?引用的时候又应该怎么区分了?下面主要来解决一下这些问题。
首先,存放的问题。假如,需要使用CreateFileA,WriteFileA,CloseHandle等api,我们会通过GetProcAddress来获取其地址,然后保存到自定义的函数原型指针中。但是,这样就会导致每个函数都有一个单独的变量,无法统一管理;所以,能不能统一存放到一块内存或数组了。最后就有了下面的方案:
1,动态获取函数地址,统一保存,通过下标(来识别)
2,调用时,对函数地址进行函数指针化,完成调用
相关代码如下:
/*
hideiat.h
*/
#pragma once
#include<Windows.h>extern PVOID* funcAddress;typedef HANDLE(WINAPI* MyCreateFileA)(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);typedef BOOL(WINAPI* MyWriteFile)(_In_ HANDLE hFile,_In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer,_In_ DWORD nNumberOfBytesToWrite,_Out_opt_ LPDWORD lpNumberOfBytesWritten,_Inout_opt_ LPOVERLAPPED lpOverlapped);typedef BOOL (WINAPI* MyCloseHandle)(_In_ _Post_ptr_invalid_ HANDLE hObject);#define MyCreateFileIndex 0
#define MyWriteFileIndex 1
#define MyCloseHandleIndex 2void initHideIat();void testhideiat();
/*
hideiat.c
*/#include<Windows.h>
#include<stdio.h>#include"hideiat.h"//PVOID funcAddress[MAX_PATH] ;
PVOID* funcAddress = NULL;void initHideIat()
{HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");funcAddress = (PVOID*)malloc(sizeof(PVOID) * MAX_PATH);if (NULL != funcAddress){if (hKernel32){funcAddress[MyCreateFileIndex] = GetProcAddress(hKernel32, "CreateFileA");funcAddress[MyWriteFileIndex] = GetProcAddress(hKernel32, "WriteFile");funcAddress[MyCloseHandleIndex] = GetProcAddress(hKernel32, "CloseHandle");}//print the func addressfor (int i = 0; i < MAX_PATH; i++){if (funcAddress[i]){printf("funcAddress[%d]:%p\n", i, funcAddress[i]);}}}}
void freeHideIat()
{//free memory
}void testhideiat()
{DWORD lpNumberOfBytesWritten = 0;//init hideiatinitHideIat();//call CreateFileAHANDLE hFile = ((MyCreateFileA)funcAddress[MyCreateFileIndex])("abc.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (INVALID_HANDLE_VALUE != hFile){((MyWriteFile)funcAddress[MyWriteFileIndex])(hFile, "123456", 6, &lpNumberOfBytesWritten, NULL);}if (hFile){((MyCloseHandle)funcAddress[MyCloseHandleIndex])(hFile);}
}
再来看看后续的反汇编代码效果:
后续:
demo里面只是调用了几个api,如果需要的话,可以将继续往函数地址数组里面添加,然后调用。