首页
社区
课程
招聘
[原创]PELoader + 多线程解密的壳样例
发表于: 2009-4-18 13:26 9735

[原创]PELoader + 多线程解密的壳样例

2009-4-18 13:26
9735
最近人变懒了,专题一直没有更新,放一个小技巧出来耍耍。是原先那个随机密码的应用和PE Loader的应用都在这个例子中有体现。一般的壳是附加到应用程序上,这个是相反的想法,把应用程序反附加到壳上.然后随机加密(在一个范围内本例子中是 0 - 0100h).壳在启动后创建0100h个线程并利用线程号解密,当唯一正确的线程解密后利用PE LOADER把正确代码加载到争取的位置并修复引入表。这个样例的很大缺陷是只有被加壳的程序的ImageBase和壳的ImageBase相同是才可以加载争取。打包程序的代码没有考虑末尾数据有些不稳定。有兴趣的朋友再继续研究吧。
样例的代码有三部分

这部分为启动部分
;; ----------------------------------------
;; code segment
;; ----------------------------------------
.code
;; ----------------------------------------
;; function statement
;; ----------------------------------------
AntiKV proto szFilePath : LPSTR
CheckPacketSuccessRate proto szFilePath : LPSTR

;; AntiAV start
AntiKV_Start:
ifdef DEBUG_ANTIAV
	lea edi, g_szTarget
else
	;; get command line
	invoke GetCommandLine							; eax = command line
	mov edi, eax									; edi = command line
	mov al, ' '										; al = 020h
	mov ecx, MAX_PATH								; ecx = MAX PATH length
	repnz scasb										; edi = target file path
endif
	;; decrypt it
	invoke AntiKV, edi
	;; exit
	invoke ExitProcess, 1

;; Anti KV
AntiKV proc uses ebx ecx edx edi esi, szFilePath : LPSTR
	;; start check the packet success rate
	invoke CheckPacketSuccessRate, edi
	test eax, eax
	jz Error_AntiKV
	;; rebuild new exe
	invoke ReBuildNewExe, szFilePath, 0100h
	lea eax, g_szSuccessPacket
	invoke crt_printf, eax
Exit_AntiKV:
	assume esi : nothing
	assume edi : nothing
	xor eax, eax
	ret
Error_AntiKV:
	lea eax, g_szCanotLoad
	invoke crt_printf, eax
	jmp Exit_AntiKV
AntiKV endp

CheckPacketSuccessRate proc uses ebx ecx edx edi esi, szFilePath : LPSTR
	LOCAL pPointer : LPVOID
	;; init data
	mov pPointer, NULL
	;; map file
	invoke MapFile2Mem, szFilePath, 0, addr pPointer, 1
	test eax, eax								; eax = file memory size
	jz Error_CheckPacketSuccessRate
	mov esi, pPointer
	add esi, dword ptr [esi+03ch]				; esi = PE header
	assume esi : ptr IMAGE_NT_HEADERS
												; eax = ImageBase
	mov eax, dword ptr [esi].OptionalHeader.ImageBase
	cmp eax, 00400000h							; check ImageBase == lprotecter ImageBase
	jnz Error_CheckPacketSuccessRate
	invoke FreeMemory, addr pPointer
	mov eax, 1									; set return success value
Exit_CheckPacketSuccessRate:
	assume esi : nothing
	ret
Error_CheckPacketSuccessRate:
	cmp pPointer, NULL
	invoke FreeMemory, addr pPointer
	jz @F
	@@:
	xor eax, eax								; eax = 0 failed value
	jmp Exit_CheckPacketSuccessRate
CheckPacketSuccessRate endp

end AntiKV_Start


这个部分为打包部分
;; ----------------------------------------
;; Name:ReBuildNewExe
;; Author:logic_yan@hotmail.com
;; Data:2009-3-3
;; Describe:pack orig program to lprotecter
;; data section
;; Arguments:
;; szFileName:file name
;; dwNewSectionSize:new section size
;; dwKeySeed:generate key seed
;; Return:
;; Success:1
;; Failed:0
;; ----------------------------------------
ReBuildNewExe proc uses ebx ecx edx esi edi, szFileName : LPSTR, dwKeySeed : DWORD
	LOCAL hFile : HANDLE
	LOCAL hMap : HANDLE
	LOCAL pLProtecter : LPVOID
	LOCAL pPackFile : LPVOID
	LOCAL dwPackFileSize : DWORD
	LOCAL dwLProtecterSize : DWORD
	LOCAL LProtecterFileInfo : FILEMAPINFO
	LOCAL pTailData : LPVOID
	LOCAL dwTailSize : DWORD
	
	;; init data
	mov pLProtecter, NULL
	mov pPackFile, NULL
	mov pTailData, NULL
	;; map pack file
	invoke MapFile2Mem, szFileName, 0, addr pPackFile, 1
	test eax, eax
	jz Error_ReBuildNewExe
	mov dwPackFileSize, eax							; eax = target file size
	;; get tail datas
	invoke GetFileTailData, pPackFile, NULL
	test eax, eax
	jz @F
	mov dwTailSize, eax								; eax = tail data
	;; allolc
	invoke AllocMemory, eax
	mov pTailData, eax
	;; get tail data
	invoke GetFileTailData, pPackFile, eax
	@@:
	;; delete file
	invoke DeleteFile, szFileName
	;; copy a LProtect
	invoke CopyFile, offset g_szLProtect, szFileName, FALSE
	;; get lportecter file info
	lea eax, LProtecterFileInfo						; eax = lprotecter file info
	invoke GetFileMapInfoByFileName, szFileName, eax
	lea eax, LProtecterFileInfo
	assume eax : ptr FILEMAPINFO
	mov eax, dword ptr [eax].dwFileAlign			; eax = lprotecter file align
	invoke PEAlign, dwPackFileSize, eax				; eax = packfile file align size
	mov ecx, eax									; ecx = packfile file align size
	;; map lprotect
	invoke MapFile2MemNotClose, szFileName, ecx, addr hFile, addr hMap, addr pLProtecter, 1
	test eax, eax
	jz Error_ReBuildNewExe
	mov dwLProtecterSize, eax						; eax = lprotecter size
	
	;; rebuild file
	mov esi, pLProtecter
	add esi, dword ptr [esi+03ch]					; esi = lprotecter pe header
	assume esi : ptr IMAGE_NT_HEADERS
	mov edi, esi
													; edi = lprotecter data section table
	lea edi, [edi+(sizeof IMAGE_NT_HEADERS+sizeof IMAGE_SECTION_HEADER+sizeof IMAGE_SECTION_HEADER)]
	assume edi : ptr IMAGE_SECTION_HEADER
	;; modify the data section
	;mov ecx, dword ptr [edi].Misc.VirtualSize
	mov ecx, dwPackFileSize							; ecx = new data section virtual size
	mov ebx, dword ptr [edi].Misc.VirtualSize		; ebx = orig data section virtual size
	mov dword ptr [edi].Misc.VirtualSize, ecx
													; eax = lprotecter file alignment
	mov eax, dword ptr [esi].OptionalHeader.FileAlignment
	add ecx, ebx									; ecx = total virtual size for data section
	invoke PEAlign, ecx, eax						; eax = new data section file alignment size
	mov dword ptr [edi].SizeOfRawData, eax
	;; set pointer
	mov edi, dword ptr [edi].PointerToRawData
	add edi, pLProtecter							; edi = to address
	mov esi, pPackFile								; esi = from address
	mov ecx, dwPackFileSize							; ecx = packet file size

	;; get the crc32 value
	invoke CRC32, esi, ecx							; eax = CRC32
	mov edx, pLProtecter							; edx = to address
	add edx, 02h									; move to 2 bytes
	mov dword ptr [edx], eax						; set CRC32 value
	
	;; get key
	invoke GetRandom, dwKeySeed
	mov ebx, eax									; bx = key
;; show debug information
ifdef DEBUG_LCODEBUILDER
	pushad
	lea eax, g_szLCodeBuilderBuffer
	invoke crt_sprintf, eax, offset g_szKeyFormat, ebx
	lea eax, g_szLCodeBuilderBuffer
	invoke crt_printf, eax
	popad
endif
	;; encode = (x xor bl) - bh
	@@:
	lodsb
	xor al, bl
	sub al, bh
	stosb
	loop @B
	
	;; modify lprotecter size of image
	mov esi, pLProtecter
	add esi, dword ptr [esi+03ch]					; esi = lprotecter pe header
	assume esi : ptr IMAGE_NT_HEADERS
	mov edi, esi
													; edi = lprotecter data section table
	lea edi, [edi+(sizeof IMAGE_NT_HEADERS+sizeof IMAGE_SECTION_HEADER+sizeof IMAGE_SECTION_HEADER)]
	assume edi : ptr IMAGE_SECTION_HEADER
	;mov edx, pPackFile
	;add edx, dword ptr [edx+03ch]					; edx = pack file pe header
	;assume edx : ptr IMAGE_NT_HEADERS
	mov ecx, dword ptr [edi].VirtualAddress
	add ecx, dword ptr [edi].Misc.VirtualSize		; ecx = lprotecter virtual size
	;mov ecx, dword ptr [esi].OptionalHeader.SizeOfImage
													; ecx = tow old size of image add
	;add ecx, dword ptr [edx].OptionalHeader.SizeOfImage
													; eax = section alignment
	mov eax, dword ptr [esi].OptionalHeader.SectionAlignment
	invoke PEAlign, ecx, eax						; eax = new size of image
	mov dword ptr [esi].OptionalHeader.SizeOfImage, eax
	
	;; modify init data size
	;mov eax, dword ptr [edi].SizeOfRawData			; eax = data section raw size
	;mov dword ptr [esi].OptionalHeader.SizeOfInitializedData, eax

	;; free file memory
	invoke FreeFileMemory, addr hFile, addr hMap, addr pLProtecter

	;; set tail data
	mov eax, dwLProtecterSize
	add eax, dwTailSize
	;; count alignment
	lea ecx, LProtecterFileInfo
	assume ecx : ptr FILEMAPINFO
	mov ecx, dword ptr [ecx].dwFileAlign			; eax = lprotecter file align
	invoke PEAlign, eax, ecx 
	;; reopen lprotect and set tail data
	xchg eax, ecx
	invoke MapFile2MemNotClose, szFileName, ecx, addr hFile, addr hMap, addr pLProtecter, 1
	test eax, eax									; eax = lprotecter size
	jz @F
	;; set tail data
	mov eax, pTailData
	invoke SetFileTailData, pLProtecter, eax, dwTailSize
	;; free file map
	invoke FreeFileMemory, addr hFile, addr hMap, addr pLProtecter
	@@:
	;; free tail data
	invoke FreeMemory, addr pTailData
	;; free memory
	invoke FreeMemory, addr pPackFile
	mov eax, 1										; set return value
Exit_ReBuildNewExe:
	assume esi : nothing
	assume edi : nothing
	assume ecx : nothing
	;assume edx : nothing
	ret
Error_ReBuildNewExe:
	cmp pPackFile, NULL								; check pPointer alloc
	jz @F
	invoke FreeMemory, addr pPackFile
	@@:
	cmp pLProtecter, NULL
	jz @F
	invoke FreeFileMemory, addr hFile, addr hMap, addr pLProtecter
	@@:
	cmp pTailData, NULL
	jz @F
	invoke FreeMemory, addr pTailData
	@@:
	xor eax, eax									; eax = 0
	jmp Exit_ReBuildNewExe
ReBuildNewExe endp


最后这一部分为一个分开的EXE程序也就是壳的主体了
编译一下的代码生成的EXE放置到与打包器同一目录下,在用打包器对其他程序进程加壳。
.586
.model flat, stdcall
option casemap:none
;; ----------------------------------------
;; header file and lib file
;; ----------------------------------------
include windows.inc
include kernel32.inc

includelib kernel32.lib

include LProtecter.inc
;; ----------------------------------------
;; data segment
;; ----------------------------------------
.data
g_pChaosCode	db 0200h dup (?)
;; ----------------------------------------
;; code segment
;; ----------------------------------------
.code
LProtecter_Start:
	push ebp
	mov ebp, esp
	push 01000h
	mov ecx, offset End_Lord - offset Lord			; ecx = lord size
	push ecx
	call PEAlign									; eax = lord alignment size
	sub esp, eax									; create runtime
	lea esi, Lord									; esi = lord pointer
	mov edi, esp									; edi = runtime space
	rep movsb										; copying
	;; modify the memory attribute
	push eax
	lea ebx, [esp+04h]
	invoke VirtualProtect, ebx, eax, PAGE_EXECUTE_READWRITE, esp
	pop eax
	call esp										; run runtime
;; ---------------------------------------------------------------------------------
NeverRun:											; never to run...
	;; some trash code
	invoke lstrcpy, edi, esi
	push ebx
	invoke CreateFile, eax, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, esp
	pop ebx
	mov esp, ebp
	pop ebp
	retn 00h
LProtecterSign:
	db 01h,09h,08h,03h
;; Lord
Lord:
;; start here
;; the delta is here
delta:
	push ebp
	mov ebp, esp
	sub esp, 01000h									; create stack (0400h * 04h) store the thread handle
	mov esi, dword ptr [ebp+04h]					; esi = never to run eip
													; esi = code first eip
	sub esi, offset NeverRun - offset LProtecter_Start
	;; find MZ sign
    @@:
	dec esi
	xor si, si
	mov ax, word ptr [esi]							; esi = kernel32.dll handle
	add ax, 0A5B3h									; cmp MZ
	jnz @B
	;; cmp PE sign
	push esi
	add esi, dword ptr [esi+03ch]					; esi = PE header
	mov ax, word ptr [esi]							; eax = 05045h
	add ax, 0BAB0h									; cmp PE
	pop esi
	jnz @B
	;; find import table
	mov edi, esi									; esi = base of image
	add edi, dword ptr [edi+03ch]					; edi = PE header
	assume edi : ptr IMAGE_NT_HEADERS
													; edi = import table directory
	lea edi, [edi].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT * sizeof IMAGE_DATA_DIRECTORY]
	mov edi, dword ptr [edi]						; edi = import RVA
	add edi, esi									; edi = import VA
	assume edi : ptr IMAGE_IMPORT_DESCRIPTOR
	mov edi, dword ptr [edi].FirstThunk
	add edi, esi									; edi = API address list
	mov edi, dword ptr [edi]						; edi = some api address
	;; find kernel32.dll handle
    @@:
	dec edi
	xor di, di
	mov ax, word ptr [edi]							; edi = kernel32.dll handle
	add ax, 0A5B3h									; cmp MZ
	jnz @B
	;; cmp PE sign
	push edi
	add edi, dword ptr [edi+03ch]					; edi = PE header
	mov ax, word ptr [edi]							; ax = 05045h
	add ax, 0BAB0h									; cmp PE
	pop edi
	jnz @B
	;; get api address
	lea eax, [ebp+08h]								; eax = lord start address
													; eax = crc32 list
	add eax, offset ApiNameCrc32 - offset delta
	mov ebx, eax
	sub ebx, offset ApiNameCrc32 - offset ApiBase	; ebx = api offset sotre list
	lea ecx, [ebp+08h]								; ecx = delta address
	push ecx										; delta address
	push ebx										; api offset store pointer
	push eax										; crc32 value list
	push edi										; dll base
	call GetApiAddress
	;; memory protect
	push ebx
	push esp										; old protect value
	push PAGE_EXECUTE_READWRITE						; new protect value
	;; get image base
	mov ecx, esi									; esi = lprotect start address
	add ecx, dword ptr [esi+03ch]
	assume ecx : ptr IMAGE_NT_HEADERS				; PE header
													; ecx = image of base
	mov ecx, dword ptr [ecx].OptionalHeader.SizeOfImage
	push ecx										; size of image
	push esi										; address of start
	mov eax, 0
	xVirtualProtect = dword ptr $-04h
	call eax										; VirtualProtect
	pop ebx											; ebx = old protect value
	
	;; create thread now
	xor edi, edi									; edi = 0
	lea ebx, [ebp-01000h]							; ebx = thread handle list pointer
	;; get evil thread stack size
	;mov ecx, esi
	;add ecx, dword ptr [ecx+03ch]					
													; ecx = evil section table
	;add ecx, sizeof IMAGE_NT_HEADERS + \
	;		 sizeof IMAGE_SECTION_HEADER + \
	;		 sizeof IMAGE_SECTION_HEADER + \
	;		 sizeof IMAGE_SECTION_HEADER
	;assume ecx : ptr IMAGE_SECTION_HEADER			; edi = evil section table
	;mov ecx, dword ptr [ecx].SizeOfRawData			; ecx = evil section raw size
	;imul ecx, ecx, 02h								; ecx = evil thread stack size
	@@:
	push ecx
	push esp										; thread id
	push 0											; create flag
	push edi										; count
	lea eax, [ebp+08h]								; eax = delta address
	add eax, offset EvilThread - offset delta
	push eax										; thread address
	;push ecx										; stack size
	push 0											; stack size
	push NULL										; lpsecurity attribute
	mov eax, 0
	xCreateThread = dword ptr $-04h
	call eax										; CreateThread
	pop ecx											; ecx = thread id
	mov dword ptr [ebx], eax						; eax = thread handle
	add ebx, 04h									; next thread handle store
	inc edi											; id count ++											
	cmp edi, MAX_DECODE_THREAD						; if edi == 1024 ?
	jb @B
	
	;; wait for muti objects
	push INFINITE									; wait for run over
	push TRUE										; wait all thread
	lea ebx, [ebp-01000h]							; ebx = thread handle list pointer
	push ebx
	push 0100h										; thread count
	mov eax, 0
	xWaitForMultipleObjects = dword ptr $-04h
	call eax										; WaitForMultipleObjects
	
	;; clear the stack
	mov esp, ebp
	pop ebp
	;; clear the ret eip
	pop eax
	;; clear 2th
	mov esp, ebp
	pop ebp
	
	;; get entry of address
	mov eax, esi
	add eax, dword ptr [esi+03ch]					; eax = PE header
	assume eax : ptr IMAGE_NT_HEADERS
													; eax = etry RVA
	mov eax, dword ptr [eax].OptionalHeader.AddressOfEntryPoint
	add eax, esi									; eax = entry VA
	push eax
	retn 00h										; goto entry pointer
	
;; ----------------------------------------
;; Name:EvilThread
;; Author:logic_yan@hotmail.com
;; Data:2009-3-4
;; Describe:evil thread decode and load
;; orig program to memory
;; Arguments:
;; 1th argument:dekey
;; Return:none
;; ----------------------------------------
EvilThread:
	push ebp
	mov ebp, esp
	call edelta
edelta:
	pop esi
	sub esi, offset edelta - offset delta			; esi = delta address
	mov esi, dword ptr [esi-04h]					; esi = never run address
													; esi = lprotect start
	sub esi, offset NeverRun - offset LProtecter_Start
	;; check the evil if exist or not
													; eax = lprotecter sign pointer
	lea eax, [esi+(offset LProtecterSign-offset LProtecter_Start)]
	mov eax, dword ptr [eax]						; eax = lprotecter sign
	add eax, 0FCF7F6FFh								; cmp sign
	jnz Exit_EvilThread
	;; get image base
	sub esi, 01000h									; esi = MZ header
	;; get the evil section
	mov edi, esi
	add edi, dword ptr [edi+03ch]
													; edi = evil section table
	add edi, sizeof IMAGE_NT_HEADERS + \
			 sizeof IMAGE_SECTION_HEADER + \
			 sizeof IMAGE_SECTION_HEADER
	assume edi : ptr IMAGE_SECTION_HEADER			; edi = evil section table
	mov ecx, dword ptr [edi].Misc.VirtualSize		; ecx = evil section virtual size
	mov edi, dword ptr [edi].VirtualAddress
	add edi, esi									; edi = evil section
	mov edx, ecx									; edx = evil section virtual size
	push 0100h										; alignment
	push edx
	call PEAlign
	mov edx, eax									; edx = alloc alignment size 
	;sub esp, edx									; create evil stack
	;mov ebx, esp									; ebx = evil buffer
	;; start decrypt
	;; alloc a memory
	push ecx										; save ecx
	@@:
	push PAGE_EXECUTE_READWRITE						; memory attribute
	push MEM_COMMIT									; create flag
	push edx										; memory size
	push NULL
	mov eax, 0
	xVirtualAlloc = dword ptr $-04h
	call eax										; VirtualAlloc
	mov ebx, eax									; ebx = pointer
	test ebx, ebx
	jz @B
	;; decode
	mov edx, dword ptr [ebp+08h]					; edx = key
	;; decode = (x xor dl) + dh
	pop ecx											; ecx = evil section virtual size
	push ebx
	push ecx
	@@:
	mov al, byte ptr [edi]							; al = value
	xor al, dl
	add al, dh
	mov byte ptr [ebx], al							; set to alloc memory
	inc ebx											; next to pointer
	inc edi											; next load pointer
	loop @B
	pop ecx											; ecx = evil section virtual size
	pop ebx											; ebx = evil memory
	
	;; get crc32 value
	push ecx										; size
	push ebx										; pointer
	call CRC32
	lea edx, [esi+02h]								; crc32 pointer
	sub eax, dword ptr [edx]						; check crc32 value
	jnz Exit_EvilThread
ifdef DEBUG_LPROTECTER
	int 03h
endif
	;; memory loader
	push ecx										; from memory size
	push ebx										; from memory
	push esi										; to memory
	call LoadFileToMemory
	
Exit_EvilThread:
	;; free memory
	push MEM_RELEASE								; free flag
	push 0											; size must be zero if release
	push ebx										; alloc address
	mov eax, 0
	xVirtualFree = dword ptr $-04h
	call eax										; VirtualFree
	mov esp, ebp
	pop ebp
	retn 04h
	
;; kernel32.dll API delta
ApiBase:
	dd offset xVirtualAlloc - offset delta
	dd offset xVirtualFree - offset delta   
	dd offset xVirtualProtect - offset delta
	dd offset xWaitForMultipleObjects - offset delta
	;dd offset xCreateFileA - offset delta
	;dd offset xWriteFile - offset delta
	;dd offset xCloseHandle - offset delta  
	dd offset xCreateThread - offset delta
	dd offset xLoadLibraryA - offset delta
	;dd offset xSleep - offset delta  
	dd offset xGetProcAddress - offset delta
	dd 0
	
;; kernel32.dll API name CRC32 list
ApiNameCrc32:
	dd 09CE0D4Ah									; VirtualAlloc
	dd 0CD53F5DDh									; VirtualFree
	dd 010066F2Fh									; VirtualProtect
	dd 0B98F54C4h									; WaitForMultipleObjects
	;dd 0553B5C78h									; CreateFileA
	;dd 0CCE95612h									; WriteFile
	;dd 0B09315F4h									; CloseHandle  
	dd 0906A06B0h									; CreateThread
	dd 03FC1BD8Dh									; LoadLibraryA
	;dd 0CEF2EDA8h									; Sleep
	dd 0C97C1FFFh									; GetProcAddress
	dd 0

;; ----------------------------------------
;; Name:LoadFileToMemory
;; Author:logic_yan@hotmail.com
;; Data:2009-3-4
;; Describe:load file to memory on section
;; alignment
;; Arguments:
;; 1th argument:to memory is size on 
;; section
;; 2th argument:from memory is size on file
;; 3th argument:from memory size
;; Return:none
;; ----------------------------------------
LoadFileToMemory:
	push ebp
	mov ebp, esp
	sub esp, 0100h									; create stack
	
	push ebx
	push ecx
	push edx
	push esi
	push edi
	
	;; copy PE header
	mov ecx, dword ptr [ebp+0Ch]
	add ecx, dword ptr [ecx+03ch]
	add ecx, sizeof IMAGE_NT_HEADERS				; ecx = 1th section table
	assume ecx : ptr IMAGE_SECTION_HEADER
	mov ecx, dword ptr [ecx].PointerToRawData		; ecx = PE header size
	mov edi, dword ptr [ebp+08h]					; edi = to memory start
	mov esi, dword ptr [ebp+0Ch]					; esi = from memory start
	rep movsb										; copying
	
	mov edx, dword ptr [ebp+0Ch]					; edx = from memory
	add edx, dword ptr [edx+03ch]					; edx = PE header
	assume edx : ptr IMAGE_NT_HEADERS
													; ecx = number of sections
	movzx ecx, word ptr [edx].FileHeader.NumberOfSections
	mov ebx, dword ptr [ebp+0Ch]					
	add ebx, dword ptr [ebx+03ch]					; edx = PE header
	add ebx, sizeof IMAGE_NT_HEADERS				; ebx = section table
	assume ebx : ptr IMAGE_SECTION_HEADER
	
CopyEachSection_Loop:
	;; write each section
	push ecx
	mov esi, dword ptr [ebp+0Ch]
	push dword ptr [ebx].VirtualAddress		; esi = section file rva
	push esi
	call RVA2Offset							; eax = section file offset
	add esi, eax							; esi = section file address
	mov edi, dword ptr [ebp+08h]
	add edi, dword ptr [ebx].VirtualAddress			; edi = section address
	mov ecx, dword ptr [ebx].Misc.VirtualSize		; ecx = section virtual size
	cmp ecx, dword ptr [ebx].SizeOfRawData			; virtual size VS raw size
	jbe @F											; if vsize <= rsize ecx = vsize 
	mov ecx, dword ptr [ebx].SizeOfRawData			; else ecx = rsize
	@@:
	rep movsb
	pop ecx											; ecx = number of sections
	add ebx, sizeof IMAGE_SECTION_HEADER			; next section table
	loop CopyEachSection_Loop
	
	;; rebuild the import table
	push dword ptr [ebp+08h]						; image base
	call BuildImportTable
	
	;; exit
Exit_LoadFileToMemory:
	assume ebx : nothing
	assume ecx : nothing
	assume edx : nothing
	pop edi
	pop esi
	pop edx
	pop ecx
	pop ebx

	mov esp, ebp									; clean stack
	pop ebp
	retn 0Ch

;; ----------------------------------------
;; Name:RVA2Offset
;; Author:logic_yan@hotmail.com
;; Data:2009-3-4
;; Describe:RVA to offset
;; Arguments:
;; 1th argument:file map
;; 2th argument:RVA
;; Return:
;; Success:offset
;; Failed:0
;; ----------------------------------------
RVA2Offset:
	push ebp
	mov ebp, esp									; create stack
	
	push ebx
	push ecx
	push edx
	push esi
	push edi
	
    mov esi, dword ptr [ebp+08h] 					; esi = file map base 
    add esi, dword ptr [esi+03ch]					; esi = PE header 
    assume esi : ptr IMAGE_NT_HEADERS 
    mov edi, dword ptr [ebp+0Ch]	 				; edi == RVA 
    mov edx, esi									; edx = PE header
    add edx, sizeof IMAGE_NT_HEADERS				; edx = 1th section table 
    movzx ecx, [esi].FileHeader.NumberOfSections	; ecx = number of sections
    assume edx : ptr IMAGE_SECTION_HEADER 
RVA2Offset_Loop:
    cmp edi, dword ptr [edx].VirtualAddress			; if ecx >= [edx].VirtualAddress
    jb Continue_RVA2Offset_Loop
    mov eax, dword ptr [edx].VirtualAddress			; eax = current section RVA					 
    add eax, [edx].SizeOfRawData 					; eax = current section end RVA
    cmp edi, eax									; if edi < eax, The address is in this section
    jae Continue_RVA2Offset_Loop
    mov eax, dword ptr [edx].VirtualAddress			; eax = current section RVA
    sub edi, eax									; edi = RVA offset
   	mov eax, dword ptr [edx].PointerToRawData		; eax = section file offset 
    add eax, edi 									; eax = file offset 
	jmp RVA2OffsetExit								; just exit
Continue_RVA2Offset_Loop:
    add edx, sizeof IMAGE_SECTION_HEADER			; edx = next section table
	loop RVA2Offset_Loop
    xor eax, eax
RVA2OffsetExit:
	assume esi : nothing
	assume edx : nothing
	
	pop edi
	pop esi
	pop edx
	pop ecx
	pop ebx
	
	mov esp, ebp
	pop ebp											; clean stack
	retn 08h
;; ----------------------------------------
;; Name:PEAlign
;; Author:logic_yan@hotmail.com
;; Data:2009-3-4
;; Describe:number to align
;; Algorithms:
;; $1 = dwTarNum / dwAlignTo
;; if remain != 0
;; $r = $1 + 1 * dwAlignTo
;; return $r
;; Arguments:
;; 1th argument:target number
;; 2th argument:alignment
;; Return:
;; Success:alignment number
;; Failed:0
;; ----------------------------------------
PEAlign:
	push ebp
	mov ebp, esp									; create stack
	push ecx
	push edx

    mov ecx, dword ptr [ebp+0Ch]					; ecx = align to
    mov eax, dword ptr [ebp+08h]					; eax = target number
    xor edx, edx									; edx = 0
    div ecx											; edx = edx / ecx
    cmp edx, 0										; cmp edx, 0
    jz AlreadyAligned
    inc eax											; eax = eax + 1
AlreadyAligned:
    mul ecx											; eax = eax * ecx
    ;; exit
    pop edx
    pop ecx     
    
    mov esp, ebp									; clear stack
    pop ebp
    retn 08h

;; ----------------------------------------
;; Name:BuildImportTable
;; Author:logic_yan@hotmail.com
;; Data:2009-3-7
;; Describe:build a new import table
;; Arguments:
;; 1th argument:file map pointer
;; Return:
;; Success:import table in file offest
;; Failed:0
;; ----------------------------------------
BuildImportTable:
	push ebp
	mov ebp, esp									; create stack
	
	push ebx
	push ecx
	push edx
	push esi
	push edi
	
	mov esi, dword ptr [ebp+08h]					; esi = file map base
	mov edi, esi
	add edi, dword ptr [esi+03ch]					; edi = PE loader
	assume edi : ptr IMAGE_NT_HEADERS
	;; check Import Table
													; edi = import table directory
	lea edi, [edi].OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY * IMAGE_DIRECTORY_ENTRY_IMPORT]
	assume edi : ptr IMAGE_DATA_DIRECTORY
	mov eax, dword ptr [edi].VirtualAddress			; eax = import table RVA
	test eax, eax
	jz Exit_BuildImportTable
	;; exist Import Table
	;invoke RVA2Offset, pAlloc, eax
	add eax, esi									; eax = import table VA
	xchg eax, edi									; edi = import table VA
	assume edi : ptr IMAGE_IMPORT_DESCRIPTOR
	;; import descriptor loop
ImportDescriptor_Loop:
	;; load dll
	mov eax, dword ptr [edi].Name1					; eax = dll name
	;invoke RVA2Offset, pAlloc, eax
	add eax, esi									; esi = file map base
	push eax										; eax = dll name
	mov eax, 0
	xLoadLibraryA = dword ptr $-04h
	call eax										; LoadLibraryA
	mov ebx, eax
	;; check use OriginalFirstThunk or FirstThunk
;	mov edx, dword ptr [edi].OriginalFirstThunk
;	test edx, edx
;	jnz UseOrignalFirstThunk
	mov edx, dword ptr [edi].FirstThunk				; edx = firstthunk
;UseOrignalFirstThunk:
	add edx, esi									; edx = api store pointer
	mov eax, dword ptr [edx]						; eax = api name THUNK_DATA
	;; get api address in one dll
GetApiAddress_Loop:
	;; ebx -> dll handler
	;invoke RVA2Offset, pAlloc, eax
	test eax, IMAGE_ORDINAL_FLAG32					; it's import by index
	jz GetApiByName
	and eax, 0FFFFh									; eax = index
	jmp GetApiNow
GetApiByName:
	add eax, esi									; eax = api name pointer VA
	assume eax : ptr IMAGE_IMPORT_BY_NAME
	lea eax, [eax].Name1							; eax = api name
	;; get api address
GetApiNow:
	push ecx
	push edx
	push eax										; eax = api name
	push ebx										; ebx = dll handle
	mov eax, 0
	xGetProcAddress = dword ptr $-04h
	call eax										; GetProcAddress
	pop edx											; edx = api store pointer
	pop ecx
	;; set api address
	mov dword ptr [edx], eax						; set address
	;; next api
	add edx, 04h									; edx = next api store address
	mov eax, dword ptr [edx]						; eax = api name RVA
	test eax, eax
	jnz GetApiAddress_Loop
	;; next dll
	add edi, sizeof IMAGE_IMPORT_DESCRIPTOR			; edi = next dll
	mov eax, dword ptr [edi].Name1					; eax = dll name RVA
	test eax, eax									; if eax == 0 then exit
	jnz ImportDescriptor_Loop
	
Exit_BuildImportTable:
	assume eax : nothing
	assume esi : nothing
	assume edi : nothing
	
	pop edi
	pop esi
	pop edx
	pop ecx
	pop ebx
	
	mov esp, ebp
	pop ebp											; clean stack
	retn 04h

;; ----------------------------------------
;; Name:SearchExport
;; Author:logic_yan@hotmail.com
;; Data:2009-2-20
;; Describe:get api address by dll export
;; Arguments:
;; 1th argument:dll base address
;; 2th argument:target crc32 value
;; Return:
;; Success:addresss api
;; Failed:0
;; ----------------------------------------
SearchExport:
	push ebp									; create stack frame
	mov ebp, esp
	; save all registry
	push ebx
	push ecx
	push edx
	push esi
	push edi
	
	mov esi, dword ptr [ebp+08h]				; esi = dll base address
	;; find export table
	add esi, dword ptr [esi+03ch]				; esi = PE header
	assume esi : ptr IMAGE_NT_HEADERS
												; edi = export table directory
	lea edi, [esi].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT * sizeof IMAGE_DATA_DIRECTORY]
	mov edi, dword ptr [edi]					; edi = export RVA
	test edi, edi								; cmp edi, 0
	jz Exit_SearchExport
	add edi, dword ptr [ebp+08h]				; edi = export VA
	assume edi : ptr IMAGE_EXPORT_DIRECTORY
	mov esi, dword ptr [edi].AddressOfNames		; esi = address of names list offset
	add esi, dword ptr [ebp+08h]				; esi = address of names list
	mov ecx, dword ptr [edi].NumberOfNames		; ecx = number of names
	xor edx, edx								; edx = 0
	;; search loop
	cld
SearchExport_Loop:
	lodsd										; eax = api name RVA
	add eax, dword ptr [ebp+08h]				; eax = api name VA
	;; work out api name length
	push esi									; save esi
	push eax									; save eax
	xor ebx, ebx								; ebx = 0
	mov esi, eax								; esi = api name VA
	;; count string length
	@@:
	lodsb										; al = the char in api name
	cmp al, 0									; if al == 0 then go end
	jz @F
	inc ebx										; ebx = count of api name
	jmp @B
	@@:											; end count api name length loop
	pop eax										; eax = api name VA
	pop esi										; esi = PE header
	;; crc32 eax
	push ebx									; ebx = the length of api name
	push eax									; eax = api name VA
	call CRC32									; eax = CRC32 value
	;; check target CRC32 value
	cmp eax, dword ptr [ebp+0Ch]				; cmping...
	jz @F										; if == then go exit
	inc edx										; edx = index of name
	loop SearchExport_Loop
	@@:											; end of search loop
	test ecx, ecx								; cmp ecx, 0
	jz @F										; go to end
	;; get api address
												; esi = address of name ordinals offset
	mov esi, dword ptr [edi].AddressOfNameOrdinals
	add esi, dword ptr [ebp+08h]				; esi = address of name ordinals address
	imul edx, edx, 02h							; edx = offset in address of name ordinals
	movzx ebx, word ptr [esi+edx]				; ebx = index of api
	imul ebx, ebx, 04h							; ebx = offset of api address
	mov edi, dword ptr [edi].AddressOfFunctions	; edi = address of functions RVA
	add edi, dword ptr [ebp+08h]				; edi = address of functions VA
	add edi, ebx								; edi = current address of function VA
	mov ecx, dword ptr [edi]					; ecx = api address RVA
	add ecx, dword ptr [ebp+08h]				; ecx = api address
	@@:											; exit SearchExport
	mov eax, ecx								; eax = api address
	Exit_SearchExport:
	;; load registry
	pop edi
	pop esi
	pop edx
	pop ecx
	pop ebx
	assume esi : nothing
	assume edi : nothing
	mov esp, ebp								; clean stack
	pop ebp
	retn 08h
	
;; ----------------------------------------
;; Name:CRC32
;; Author:logic_yan@hotmail.com
;; Data:2009-2-20
;; Describe:work out CRC32 value
;; Arguments:
;; 1th:string ptr
;; 2th:string ptr count
;; Return:
;; Success:CRC32 value
;; Failed:0
;; ----------------------------------------
CRC32:
    push ebp										; create stack
    mov ebp, esp
    sub esp, 0400h
   	;; savel registry
    push ebx
 	push ecx
 	push edx
 	push esi
 	push edi
    ;; dynamic create CRC32 table
    xor ecx, ecx									; ecx = 0
    lea esi, [ebp-0400h]							; esi = crc32 table pointer
    CreateCRC32Tbl_Loop1:
    cmp ecx, 0100h
    jz EndCreateCRC32Tbl_Loop1
    mov edx, ecx
    push ecx
    mov ecx, 08h
    CreateCRC32Tbl_Loop2:
    test edx, 01h
    jz CreateCRC32Tbl_Loop2_Tmp1
    shr edx, 01h
    xor edx, 0EDB88320h
    jmp CreateCRC32Tbl_Loop2_Tmp2
    CreateCRC32Tbl_Loop2_Tmp1:
    shr edx, 01h
    CreateCRC32Tbl_Loop2_Tmp2:
    dec ecx
    jnz CreateCRC32Tbl_Loop2
    pop ecx
    mov dword ptr [esi+ecx*04h], edx
    inc ecx
 	jmp CreateCRC32Tbl_Loop1
    EndCreateCRC32Tbl_Loop1:
    
    ;; calcu CRC32 value
    mov edx, 0FFFFFFFFh								; edx = 0FFFFFFFFh
    mov ecx, dword ptr [ebp+0Ch]					; ecx = string length
    mov edi, dword ptr [ebp+08h]					; edi = string ptr
    @@:
    mov al, byte ptr [edi]							; al = char of string
    movzx eax, al
    xor eax, edx
    and eax, 0FFh
    mov eax, dword ptr [esi+eax*04h]
    shr edx, 08h
    and edx, 00FFFFFFh
    xor edx, eax
    inc edi
    dec ecx
    jnz @B
    xor edx, 0FFFFFFFFh
    mov eax, edx
Exit_EndCRC32:   
    pop edi
    pop esi
    pop edx
    pop ecx
    pop ebx
    mov esp, ebp									; clean stack
    pop ebp
    retn 08h
    
;; ----------------------------------------
;; Name:GetApiAddress
;; Author:logic_yan@hotmail.com
;; Data:2009-3-4
;; Describe:get api address
;; Arguments:
;; 1th:dll base
;; 2th:crc32 value list pointer
;; 3th:api offset store list pointer
;; 4th:image of base
;; Return:none
;; ----------------------------------------
GetApiAddress:
	push ebp
	mov ebp, esp									; create stack
	
	push esi
	push edi
	push edx
	push ebx
	push ecx
	
	mov edx, dword ptr [ebp+08h]					; edx = dll base
	mov esi, dword ptr [ebp+0Ch]					; esi = crc32 value list
	mov edi, dword ptr [ebp+010h]					; edi = api offset store list pointer
	mov ecx, dword ptr [ebp+014h]					; ecx = base address
	lodsd											; eax = CRC32 value
ListCRC32List_Loop:
	push eax
	push edx
	call SearchExport								; search dll export table
	test eax, eax
	jz @F
	mov ebx, dword ptr [edi]						; ebx = api delta
	add ebx, ecx									; ebx = api store pinter address
	mov dword ptr [ebx], eax						; set api address
	@@:
	add edi, 04h									; edi = next store address
	lodsd											; eax = CRC32 value
	test eax, eax
	jnz ListCRC32List_Loop
	
	;; exit
	pop ecx
	pop ebx
	pop edx
	pop edi
	pop esi
	mov esp, ebp									; clean stack
	pop ebp
	retn 010h
End_Lord:

end LProtecter_Start


有兴趣的朋友可以搞的稳定些。。。

[课程]Android-CTF解题方法汇总!

收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 25
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
-。-
不愧是玩命大叔。动作真快
2009-4-18 13:32
0
雪    币: 647
活跃值: (564)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
这贴要顶 学习
2009-4-18 14:30
0
雪    币: 350
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
   膜拜.    能不能介绍一下怎么才能把汇编代码写的这么熟练
2009-4-18 19:14
0
雪    币: 124
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
先收藏了,以后慢慢看
2009-4-20 08:50
0
雪    币: 347
活跃值: (25)
能力值: ( LV9,RANK:420 )
在线值:
发帖
回帖
粉丝
6
纯友情支持。。。
2009-4-20 14:11
0
雪    币: 255
活跃值: (37)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
看见玩命 就顶!!!啊
2009-4-20 17:07
0
游客
登录 | 注册 方可回帖
返回
//