构造无导入表的win32asm程序

这篇文章展示了如何创建一个不依赖导入表的程序,通过直接调用内存中的API地址来执行函数,如GetProcAddress、LoadLibrary和FreeLibrary,以加载和使用kernel32.dll和user32.dll中的函数。
摘要由CSDN通过智能技术生成
;---------------------------------------------
;构造无导入表的程序
;By lx 2023.2.3
;---------------------------------------------
.386
.model flat,stdcall
option casemap:none

include windows.inc

include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib 

_PROCVAR0 typedef proto
_PROCVAR1 typedef proto :dword
_PROCVAR2 typedef proto :dword,:dword
_PROCVAR3 typedef proto :dword,:dword,:dword
_PROCVAR4 typedef proto :dword,:dword,:dword,:dword
PROCVAR0 typedef ptr _PROCVAR0
PROCVAR1 typedef ptr _PROCVAR1
PROCVAR2 typedef ptr _PROCVAR2
PROCVAR3 typedef ptr _PROCVAR3
PROCVAR4 typedef ptr _PROCVAR4

.data
	;MessageBox 
	_MessageBox  PROCVAR4 ?
	;GetProcAddress
	_GetProcAddress PROCVAR2 ?
	;LoadLibrary
	_LoadLibrary PROCVAR1 ?
	;FreeLibrary
	_FreeLibrary PROCVAR1 ?
	szTestBuffer db 256 dup(0)
	szFmt db '%08x',0
	hKernel dd ?
	hUser dd ?
.const
	sz_GetProcAddress db 'GetProcAddress',0
	sz_LoadLibrary db 'LoadLibraryA',0
	sz_FreeLibrary db 'FreeLibraryA',0
	sz_MessageBox db 'MessageBoxA',0
	szUserDLL db 'user32.dll',0
	szText db 'This easy',0
.code
	;获取kernel32.dll基地址
	_getKernelBase proc dwEsp
		
		local @ret
		
		mov @ret,0
		pushad
		mov edi,dwEsp
		and edi,0ffff0000h
		.repeat
			mov esi,edi
			.if word ptr [esi] == IMAGE_DOS_SIGNATURE
				add esi,[esi+3ch]
				.if word ptr [esi] == IMAGE_NT_SIGNATURE
					mov @ret,edi
					.break
				.endif
			.endif
			sub edi,10000h
		.until edi<=70000000h
		popad
		mov eax,@ret
		ret
		
	_getKernelBase endp
	
	;获取导出函数地址
	_getApi proc _hModule,_lpApi
		
		local @dwLen
		local @ret
		mov @dwLen,0
		mov @ret,0
		
		pushad
		
		mov edi,_lpApi
		xor al,al
		mov ecx,-1
		cld
		repnz scasb
		mov ecx,edi
		sub ecx,_lpApi
		mov @dwLen,ecx
		
		mov esi,_hModule
		add esi,[esi+3ch]
		assume esi:ptr IMAGE_NT_HEADERS
		mov esi,[esi].OptionalHeader.DataDirectory.VirtualAddress
		add esi,_hModule
		assume esi:ptr IMAGE_EXPORT_DIRECTORY
		
		xor edx,edx
		mov ebx,[esi].AddressOfNames
		add ebx,_hModule
		.repeat
			push esi
			mov edi,[ebx]
			add edi,_hModule
			mov esi,_lpApi
			mov ecx,@dwLen
			repz cmpsb
			.if ZERO?
				pop esi
				jmp @F
			.endif
			pop esi
			add ebx,4
			inc edx
		.until edx>=[esi].NumberOfNames
		jmp _ret
		;ebx 为目的下标
	@@:
		sub ebx,_hModule
		sub ebx,[esi].AddressOfNames
		shr ebx,1
		add ebx,[esi].AddressOfNameOrdinals
		add ebx,_hModule
		movzx eax,word ptr [ebx]
		shl eax,2
		add eax,[esi].AddressOfFunctions
		add eax,_hModule
		mov eax,[eax]
		add eax,_hModule

		mov @ret,eax
		
	_ret:
		assume esi:nothing
		popad
		mov eax,@ret
		ret
		
	_getApi endp
	
	start:
		
		push [esp]
		call _getKernelBase
		mov hKernel,eax
		invoke _getApi,hKernel,addr sz_GetProcAddress
		mov _GetProcAddress,eax
		invoke _GetProcAddress,hKernel,offset sz_LoadLibrary
		mov _LoadLibrary,eax
		invoke _GetProcAddress,hKernel,offset sz_FreeLibrary
		mov _FreeLibrary,eax
		invoke _LoadLibrary,offset szUserDLL
		mov hUser,eax
		invoke _GetProcAddress,hUser,offset sz_MessageBox
		mov _MessageBox,eax
		invoke _MessageBox,NULL,offset szText,NULL,0
	end start
	
	
	
	
	
	
	
	
	
	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值