masm32汇编寻找kernel32.dll基地址,查找LoadLibraryA和GetProcAddress函数地址

一、背景

对于一个PE文件病毒来说,没有引入函数节的支撑,同时,也不应该全部使用静态库(这样做,不仅会大大增加程序代码,很容易被用户或者杀毒软件发现,同时也不具有通用性,对于不同的计算机平台,甚至不同的主机,都可能得到不同的结果,显然,这不是我们不希望的),所有,制作一个PE文件病毒的首要步骤就是寻找kernel32.dll基地址,根据模块地址,查找到LoadLibraryA和GetProcAddress函数的地址,通过这两个函数,我们就可以使用所有Windows的库函数了。同时,由于不清楚病毒代码会被加载到什么地方,病毒代码的重定位也是必须的。

二、主要做些什么

1、代码重定位
2、寻找kernel32.dll模块基地址(提供了两种解决方案)
3、通过kernel32.dll查找到LoadLibraryA和GetProcAddress函数加载地址
4、通过LoadLibraryA和GetProcAddress两个函数加载我们需要的函数

三、环境

操作系统:windows10家庭版1903
汇编器:masm32 6.14.8444
注:link的时候可能会出错,把lib.asm里面的函数放到mycode.asm里,进行相应修改就可以了。

四、代码

win32.inc

.686
.model flat,stdcall
assume fs:nothing

option casemap:none;case sensetive
      ;include E:\masm32\include\windows.inc
      ;include E:\masm32\include\kernel32.inc
      ;include E:\masm32\include\user32.inc
	  ;include E:\masm32\include\msvcrt.inc
      ;includelib E:\masm32\lib\kernel32.lib
      ;includelib E:\masm32\lib\user32.lib
	  ;includelib E:\masm32\lib\msvcrt.lib
	  
	 
__kernel32Unicode Macro
	forc	char,kernel32.dll
			byte	'&char&'
			byte	0
	endm
	word	0
endm

lib.asm

include	win32.inc

public	fun_GetKernel32Addr_f
public	fun_GetKernel32Addr_t
public	fun_GetFunA
public	fun_strcmp
public	fun_strcmp_nocase
public	fun_strcmp_nocaseU

	.code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;get kernel32.dll address
;para1:	one address in kernel32.dll
;ret: kernel32Address
fun_GetKernel32Addr_f	proc
	push	ebp
	mov		ebp,esp
	
	mov		eax,[ebp+8h]
	and		eax,0ffff0000h
fun_GetKernel32Addr_f_l1:
	cmp		word ptr [eax],'ZM'
	je		fun_GetKernel32Addr_f_l2
	sub		eax,010000h
	jmp 	fun_GetKernel32Addr_f_l1

fun_GetKernel32Addr_f_l2:
	leave
	ret 4h
	
fun_GetKernel32Addr_f	endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;para1	kernel32NameString
;ret:	kernel32Address
fun_GetKernel32Addr_t:
	push	ebp
	mov		ebp,esp
	push	edi
	
	mov		edi,fs:[30h]
	mov		edi,[edi + 0ch]
	mov		edi,[edi + 01ch]

fun_GetKernel32Addr_t_l1:
	push	[edi + 20h]
	push	[ebp + 08h]
	call	fun_strcmp_nocaseU
	cmp		eax,1h
	je		fun_GetKernel32Addr_t_l2
	mov		edi,[edi]
	jmp		fun_GetKernel32Addr_t_l1
	
fun_GetKernel32Addr_t_l2:
	mov		eax,[edi + 08h]
	
	pop		edi
	leave
	ret 4h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;get funtion address in kernel32.dll
;para1	export directory table virtual address
;para2:	search function name string
;para3:	kernel32.dll address
;ret:	function virtual address
fun_GetFunA:
	push	ebp
	mov		ebp,esp
	sub		esp,010h

	;export address table
	mov		eax,[ebp+8h]
	mov		eax,[eax + 1ch]
	add		eax,[ebp + 010h]
	mov		[ebp-4h],eax
	;export name table
	mov		eax,[ebp+8h]
	mov		eax,[eax + 20h]
	add		eax,[ebp + 010h]
	mov		[ebp-8h],eax
	;export ordinal table
	mov		eax,[ebp+8h]
	mov		eax,[eax + 24h]
	add		eax,[ebp + 010h]
	mov		[ebp-0ch],eax
	;i
	mov		dword ptr [ebp-010h],0h
	
fun_GetFunA_loop:
	mov		eax,[ebp-8h]
	mov		edx,[ebp-010h]
	mov		ecx,[eax + edx * 4]
	add		ecx,[ebp + 010h]
	push	ecx
	push	[ebp+0ch]
	call	fun_strcmp_nocase
	cmp		eax,1h
	je		fun_GetFunA_ret
	inc 	dword ptr [ebp-010h]
	jmp		fun_GetFunA_loop

fun_GetFunA_ret:
	mov		eax,[ebp-0ch]
	mov		edx,[ebp-010h]
	xor		ecx,ecx
	mov		cx,[eax + edx * 2]
	mov 	eax,[ebp-4h]
	mov		eax,[eax + ecx * 4]
	add 	eax,[ebp + 010h]
	
	leave
	ret 0ch
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;campare string
;para1:string1
;para2:string2
;ret:	equal=1,not equal=0
fun_strcmp		proc
	push	ebp
	mov		ebp,esp

	mov 	eax,[ebp+0ch]
	mov 	ecx,[ebp+8h]

fun_strcmp_loop:
	mov		dl,[eax]
	cmp		dl,[ecx]
	jne		fun_strcmp_ret0
	cmp		dl,0
	je		fun_strcmp_ret1
	inc		eax
	inc		ecx
	jmp		fun_strcmp_loop

fun_strcmp_ret0:
	mov		eax,0
	jmp		fun_strcmp_ret

fun_strcmp_ret1:
	mov 	eax,1

fun_strcmp_ret:
	leave
	ret 8h
	
fun_strcmp		endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;campare string nocase
;para1:string1
;para2:string2
;ret:	equal=1,not equal=0
fun_strcmp_nocase		proc
	push	ebp
	mov		ebp,esp

	mov 	eax,[ebp+0ch]
	mov 	ecx,[ebp+8h]

fun_strcmp_nocase_loop:
	mov		dl,[eax]
	sub		dl,[ecx]
	jz		fun_strcmp_nocase_zero
	cmp		dl,20h
	je		fun_strcmp_nocase_final
	cmp		dl,-20h
	je		fun_strcmp_nocase_final
	jmp		fun_strcmp_nocase_ret0
	
fun_strcmp_nocase_zero:
	cmp		byte ptr [ecx],0
	je		fun_strcmp_nocase_ret1
	
fun_strcmp_nocase_final:
	inc		eax
	inc		ecx
	jmp		fun_strcmp_nocase_loop

fun_strcmp_nocase_ret0:
	mov		eax,0
	jmp		fun_strcmp_nocase_ret

fun_strcmp_nocase_ret1:
	mov 	eax,1

fun_strcmp_nocase_ret:
	leave
	ret 8h
	
fun_strcmp_nocase		endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;campare string nocase unicode
;para1:string1
;para2:string2
;ret:	equal=1,not equal=0
fun_strcmp_nocaseU		proc
	push	ebp
	mov		ebp,esp

	mov 	eax,[ebp+0ch]
	mov 	ecx,[ebp+8h]

fun_strcmp_nocaseU_loop:
	mov		dx,[eax]
	sub		dx,[ecx]
	jz		fun_strcmp_nocaseU_zero
	cmp		dx,20h
	je		fun_strcmp_nocaseU_final
	cmp		dx,-20h
	je		fun_strcmp_nocaseU_final
	jmp		fun_strcmp_nocaseU_ret0
	
fun_strcmp_nocaseU_zero:
	cmp		word ptr [ecx],0
	je		fun_strcmp_nocaseU_ret1
	
fun_strcmp_nocaseU_final:
	add		eax,2
	add		ecx,2
	jmp		fun_strcmp_nocaseU_loop

fun_strcmp_nocaseU_ret0:
	mov		eax,0
	jmp		fun_strcmp_nocaseU_ret

fun_strcmp_nocaseU_ret1:
	mov 	eax,1

fun_strcmp_nocaseU_ret:
	leave
	ret 8h
	
fun_strcmp_nocaseU	endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

end

mycode.asm

include win32.inc

extern	fun_GetKernel32Addr_t:near
extern	fun_GetFunA:near
	
	.code
start:
	;获取imageBase偏移
	call	getOffset
getOffset:
	pop 	ebx
	sub		ebx,offset getOffset
	
	;查找&&存储kernel32.dll基地址
	lea		eax,[ebx + offset kernel32NameString]
	push	eax
	call	fun_GetKernel32Addr_t
	mov		[ebx + offset kernel32Addr],eax
	
	;查找&&存储引出目录表地址
	mov		eax,[eax + 3ch]
	add		eax,78h
	add		eax,[ebx + offset kernel32Addr]
	mov		eax,[eax]
	add		eax,[ebx + offset kernel32Addr]
	mov		[ebx + offset exportDirTAddr],eax
	
	;查找LoadLibraryA,GetProcAddress函数地址&&存储
	push	[ebx + offset kernel32Addr]
	lea		ecx,[ebx + offset LoadLNameString]
	push	ecx
	push	dword ptr [ebx + offset exportDirTAddr]
	call	fun_GetFunA
	mov		[ebx + offset LoadLibraryAddr],eax
	
	push	[ebx + offset kernel32Addr]
	lea		ecx,[ebx + offset GetPANameString]
	push	ecx
	push	dword ptr [ebx + offset exportDirTAddr]
	call	fun_GetFunA
	mov		[ebx + offset GetProcAddressAddr],eax
	
	;加载user32.dll
	lea		eax,[ebx + offset user32NameString]
	push	eax
	mov		eax,[ebx + offset LoadLibraryAddr]
	call	eax
	mov		[ebx + offset user32Addr],eax
	
	;查找FindFirstFile,FindNextFile,ExitProcess, MessageBoxA函数地址&&存储
	lea		eax,[ebx + offset FindFFNameString]
	push	eax
	push	[ebx + offset kernel32Addr]
	mov		eax,[ebx + offset GetProcAddressAddr]
	call	eax
	mov		[ebx + offset FindFirstFileAddr],eax
	
	lea		eax,[ebx + offset FindNFNameString]
	push	eax
	push 	[ebx + offset kernel32Addr]
	mov		eax,[ebx + offset GetProcAddressAddr]
	call	eax
	mov		[ebx + offset FindNextFileAddr],eax
	
	lea		eax,[ebx + offset ExitPNameString]
	push	eax
	push 	[ebx + offset kernel32Addr]
	mov		eax,[ebx + offset GetProcAddressAddr]
	call	eax
	mov		[ebx + offset ExitProcessAddr],eax
	
	lea		eax,[ebx + offset MessageBNameString]
	push	eax
	push 	[ebx + offset user32Addr]
	mov		eax,[ebx + offset GetProcAddressAddr]
	call	eax
	mov		[ebx + offset MessageBoxAddr],eax
	
	;执行操作
	push 40h+1000h
	lea eax,[ebx + offset msgtitle]
	push eax
	lea eax, [ebx + offset content]
	push eax
	push 0
	mov		eax,[ebx + offset MessageBoxAddr]
	call	eax
	;mov		eax,00401000h
	;jmp		eax
	push 0
	mov		eax,[ebx + offset ExitProcessAddr]
	call	eax
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;data in section code
kernel32Addr		dword	0
user32Addr			dword	0
exportDirTAddr		dword	0
LoadLibraryAddr		dword	0
GetProcAddressAddr	dword	0
FindFirstFileAddr	dword	0
FindNextFileAddr	dword	0
MessageBoxAddr		dword	0
ExitProcessAddr		dword	0
LoadLNameString		byte	"LoadLibraryA",0
GetPANameString		byte	"GetProcAddress",0
FindFFNameString	byte	"FindFirstFileA",0
FindNFNameString	byte	"FindNextFileA",0
MessageBNameString	byte	"MessageBoxA",0
ExitPNameString		byte	"ExitProcess",0
user32NameString	byte	"user32.dll",0
kernel32NameString:			__kernel32Unicode

msgtitle	byte	"MessageBox program",0
content		byte	"My name is hs, and I like computer, and this is a MessageBox program",0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	end start

make.bat

@echo off
@set project=E:\masm32
@echo on

%project%\BIN\ML /c /coff /Zi /Fl %1.asm
@echo off
if errorlevel 1 goto terminate
@echo on
%project%\BIN\LINK %1.obj lib.obj /subsystem:windows /release /section:.text,rw
@echo off
if errorlevel 1 goto terminate
@echo on

:terminate
@echo on

你可能感兴趣的:(kernel32基地址,病毒重定位)