重新编译开源代码绕过杀毒软件(无导入表编译)

本文介绍如何通过重新编译开源代码,避免使用导入表中的敏感API,以绕过杀毒软件的静态查杀。讨论了PE文件结构、API函数确定、GetProcAddress的使用,以及如何在不依赖LoadLibraryW的情况下获取kernel32.dll的地址。
摘要由CSDN通过智能技术生成

重新编译开源代码绕过杀毒软件

由于大多数加壳软件并不会修改被修改文件的导入表,所以杀毒软件除了计算整个可执行文件的hash值外还会计算pe文件的导入表(import address tables)的hash值,通常采用的hash算法为MD5,本文旨在使木马文件不再依赖导入表,从而绕过部分静态查杀。

阅读本文前置知识

  1. pe文件结构
  2. windows api
  3. c/c++语言编程基础

敏感api调用

杀软会对iat表中的一些敏感函数进行检查,如CreateRemoteThread,VirtualAlloc等,CreateRemoteThread的功能是在其他进程中创建一个线程,众所周知线程就是实际的执行体,那么我们的这个行为就会被杀软关注并检查,那么我们如何解决这个问题呢?

确定APi函数

在我们尝试规避检测之前我们需要先确定哪一些是API函数,比如下面这个代码:

#include<stdio.h>
#include<Windows.h>

int main()
{
   
	printf("hello world\n");
	MessageBoxW(0, TEXT("hello world"), 0, 0);
	return 0;
}

如果你不确定哪一个函数是windows的api的话,我们可疑先把他编译出来,然后通过pe查看工具来定位api函数,这里我使用了大家都很熟悉的printf和messageboxW函数。


->Import Table

  1. ImageImportDescriptor:

OriginalFirstThunk:  0x0001B2F0
TimeDateStamp:       0x00000000  (GMT: Thu Jan 01 00:00:00 1970) 
ForwarderChain:      0x00000000
Name:                0x0001B45A  ("USER32.dll")
FirstThunk:          0x0001B098

Ordinal/Hint API name
------------ ---------------------------------------
0x0286       "MessageBoxW"

  2. ImageImportDescriptor:

OriginalFirstThunk:  0x0001B320
TimeDateStamp:       0x00000000  (GMT: Thu Jan 01 00:00:00 1970)
ForwarderChain:      0x00000000
Name:                0x0001B52C  ("VCRUNTIME140D.dll")
FirstThunk:          0x0001B0C8

Ordinal/Hint API name
------------ ---------------------------------------
0x001C       "__current_exception"
0x001D       "__current_exception_context"
0x0048       "memset"
0x0035       "_except_handler4_common"
0x002E       "__vcrt_GetModuleFileNameW"
0x002F       "__vcrt_GetModuleHandleW"
0x0031       "__vcrt_LoadLibraryExW"
0x0025       "__std_type_info_destroy_list"

  3. ImageImportDescriptor:

OriginalFirstThunk:  0x0001B370
TimeDateStamp:       0x00000000  (GMT: Thu Jan 01 00:00:00 1970)
ForwarderChain:      0x00000000
Name:                0x0001B7EE  ("ucrtbased.dll")
FirstThunk:          0x0001B118

Ordinal/Hint API name
------------ ---------------------------------------
0x0545       "strcat_s"
0x0111       "_exit"
0x02EE       "_seh_filter_dll"
0x0197       "_initialize_onexit_table"
0x02E2       "_register_onexit_function"
0x010C       "_execute_onexit_table"
0x00E8       "_crt_atexit"
0x00E7       "_crt_at_quick_exit"
0x00E0       "_controlfp_s"
0x0566       "terminate"
0x03C9       "_wmakepath_s"
0x03E5       "_wsplitpath_s"
0x057F       "wcscpy_s"
0x0073       "__p__commode"
0x0476       "exit"
0x019A       "_initterm_e"
0x0199       "_initterm"
0x0162       "_get_initial_narrow_environment"
0x0196       "_initialize_narrow_environment"
0x00DC       "_configure_narrow_argv"
0x0081       "__setusermatherr"
0x02F2       "_set_app_type"
0x02EF       "_seh_filter_exe"
0x0015       "_CrtDbgReportW"
0x0014       "_CrtDbgReport"
0x0082       "__stdio_common_vfprintf"
0x0045       "__acrt_iob_func"
0x0549       "strcpy_s"
0x02FA       "_set_new_mode"
0x00DB       "_configthreadlocale"
0x02E3       "_register_thread_local_exe_atexit_callback"
0x00C5       "_c_exit"
0x00CA       "_cexit"
0x0070       "__p___argv"
0x006F       "__p___argc"
0x02F7       "_set_fmode"
0x008E       "__stdio_common_vsprintf_s"

  4. ImageImportDescriptor:

OriginalFirstThunk:  0x0001B258
TimeDateStamp:       0x00000000  (GMT: Thu Jan 01 00:00:00 1970)
ForwarderChain:      0x00000000
Name:                0x0001B9D2  ("KERNEL32.dll")
FirstThunk:          0x0001B000

Ordinal/Hint API name
------------ ---------------------------------------
0x02D0       "GetStartupInfoW"
0x058C       "TerminateProcess"
0x0217       "GetCurrentProcess"
0x02AE       "GetProcAddress"
0x01AB       "FreeLibrary"
0x05CE       "VirtualQuery"
0x02B4       "GetProcessHeap"
0x0349       "HeapFree"
0x0345       "HeapAlloc"
0x0261       "GetLastError"
0x0278       "GetModuleHandleW"
0x0386       "IsProcessorFeaturePresent"
0x021C       "GetCurrentThreadId"
0x056D       "SetUnhandledExceptionFilter"
0x05AD       "UnhandledExceptionFilter"
0x0363       "InitializeSListHead"
0x02E9       "GetSystemTimeAsFileTime"
0x0218       "GetCurrentProcessId"
0x044D       "QueryPerformanceCounter"
0x05FE       "WideCharToMultiByte"
0x03EF       "MultiByteToWideChar"
0x0462       "RaiseException"
0x037F       "IsDebuggerPresent"

现在我们确定了messageboxw是windows函数外,还看到很多并非我们指定的函数加载,这是由于在进程初始化前并不单单执行我们定义的代码,还会调用其他的系统函数,至于printf函数至少最外层并非windows api函数,这里不过多讲解。

GetProcAddress函数

在确定api函数后,我们可以通过windows提供的另一个函数来确定其他函数的函数地址,获得地址后,我们可以通过定义函数指针的方式来执行函数。

#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值