;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
; Unwrap Thunk [petite/aspack/...] (C) G-RoM in 1999, 2000
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
;
; Hydra example Plugin
;
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
; Started on    : 02nd September 2000
; Latest update : 06th September 2000
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北

		BITS 32

		%include "pedata.inc" ; Structs
		%include "memio.inc"  ; Protos

;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
; Public definitions.
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
global UnwrapThunk			; Our export function
global _Start@12			; Main

;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
; Code definition.
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
SEGMENT .bss	USE32 CLASS=BSS
OpcodeTable	RESB	2048
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
; Code definition.
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
SEGMENT .text	USE32 CLASS=CODE
%include "lde32.inc"

;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
; Detect DLL Name of given thunk [Fast mode]
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北

;鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍
;esp+4 : IAT thunk
;esp+8 : DLL List
;
;eax=1 if member.
;鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍
IsFromDLL:
	push	ebp
	mov	ebp, esp
	push	esi
	push	edi
	push	edx
	push	ecx
	push	ebx

	mov	esi, [ebp+0ch]		; DLLList
	mov	edx, [ebp+08h]		; Thunk
	xor	eax, eax		; RetVal
.LoopScan:
	cmp	[esi+DLLList.ModPath], eax             ; DLLList finished ?
	jz	.Failure

	mov	ebx, [esi+DLLList.Base] ; Thunk must be DLL Area
	cmp	edx, ebx
	jb	.CheckNextDLL
	add	ebx, [esi+DLLList.Size]
	cmp	edx, ebx
	jbe	.Success
.CheckNextDLL:
	add	esi, DLLList_size
	jmp	short .LoopScan
.Success:
	xor	eax, eax
	inc	eax
.Failure:
	pop	ebx
	pop	ecx
	pop	edx
	pop	edi
	pop	esi
	pop	ebp
	ret	08h
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
; Load ALL IAT thunk.
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北

;鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍
;esp+4 : ThunkSlot
;esp+8 : PE Buffer.
;esp+c : PE Infos.
;esp+10: DLL List.
;
;eax=thunk on success.
;鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍
UnwrapThunk:
	push	ebp
	mov	ebp, esp

%define ThunkSlot ebp+08h
%define PEBuffer  ebp+0ch
%define PEInfos   ebp+10h
%define DLLList   ebp+14h

	push	edx
	push	esi
	push	edi
	push	ecx

;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
; Init. Pointers.
;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
	mov	edx, [PEInfos]
	mov	esi, [ThunkSlot]
	sub	esi, [PEBuffer]
	add	esi, [edx+PEStruc.ImageBase]	; Relocate

;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
; Check Thunk Range.
;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
.try_again:
	mov	eax, [esi]

	or	eax, eax
	jz	.ReturnEAX
	js	.ReturnEAX

	mov	esi, [ThunkSlot]
;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
; Is this thunk a Direct DLL Member ?
;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
	push	eax
	push	dword [DLLList]
	push	eax
	Call	IsFromDLL
	test	eax, eax
	pop	eax
	jnz	.ReturnEAX
;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
; Check if valid memory.
;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
	push	eax
	push	byte 9
	push	eax
	call	IsBadPtr
	or	eax,eax
	pop	eax
	jnz	.ReturnEAX
;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
; Direct API Jump ? (jmp API)
;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
	cmp	byte [eax], 0xE9	; jmp rel32
	jnz	.NextTrick

	add	eax, [eax+1]
	add	eax, byte 5
	mov	[esi], eax
	jmp	short .try_again

.NextTrick:
;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
; Aspack trick ? (push imm32/jmp rel32)
;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
	cmp	byte [eax], 0x68	; push imm32
	jne	.UseDecoder

	cmp	byte [eax+5], 0xE9	; jmp rel32
	jne	.UseDecoder

	mov	eax,[eax+1]
	mov	[esi], eax
	jmp	.ReturnEAX
.UseDecoder:
	xor	ecx, ecx
	xor	edi, edi
.LoopDecode:
	cmp	ecx, 20h		; maximum bytes to decode
	jae	.ReadESI
	add	edi, eax

	push	edi
	push	dword OpcodeTable
	Call	disasm_main
	add	ecx, eax

	cmp	byte [edi], 0xE9
	jnz	short .LoopDecode
	sub	ecx, eax
	mov	eax, edi

	add	eax, [eax+1]
	add	eax, byte 5
	sub	eax, ecx
	mov	[esi], eax
	jmp	short .ReturnEAX
.ReadESI:
	mov	eax, [esi]
.ReturnEAX:
	pop	ecx
	pop	edi
	pop	esi
	pop	edx
	pop	ebp

%undef ThunkSlot
%undef PEBuffer
%undef PEInfos
%undef DLLList

	retn	10h

;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
; DLLMAIN.
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北

;鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍
;
;鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍鞍
_Start@12:
	push	dword OpcodeTable
	Call	disasm_init

	push	byte 01h
	pop	eax
	retn	0ch
