📄 protogen.bat
字号:
IsLibExtensionSpecified proc uses esi ebx pLibraryPath:LPSTR
_mov ebx, FALSE ; assume error
mov esi, pLibraryPath
.if esi != NULL
invoke fstrlen, esi
add esi, eax
sub esi, 4 ; ".lib"
invoke lstrcmpi, addr g_szLibExtension, esi
.if eax == 0
inc ebx ; OK
.endif
.endif
return ebx
IsLibExtensionSpecified endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; IsFullPathSpecified
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IsFullPathSpecified proc uses esi pLibraryPath:LPSTR
mov esi, pLibraryPath
mov ecx, $invoke(fstrlen, esi)
; search for back slash
.while ecx
mov al, [esi]
.break .if al == '\'
inc esi
dec ecx
.endw
return ecx
IsFullPathSpecified endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; CloseLibrary
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CloseLibrary proc
.if g_pLibraryImage != NULL
invoke UnmapViewOfFile, g_pLibraryImage
_mov g_pLibraryImage, NULL
.endif
.if g_hLibraryMapping != NULL
invoke CloseHandle, g_hLibraryMapping
_mov g_hLibraryMapping, NULL
.endif
.if g_hLibraryFile != INVALID_HANDLE_VALUE
invoke CloseHandle, g_hLibraryFile
_mov g_hLibraryFile, INVALID_HANDLE_VALUE
.endif
ret
CloseLibrary endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; OpenLibrary
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
OpenLibrary proc uses ebx pszLibraryName:LPSTR
and ebx, FALSE ; clear flag OK
invoke CreateFile, pszLibraryName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL
.if eax != INVALID_HANDLE_VALUE
mov g_hLibraryFile, eax
invoke CreateFileMapping, g_hLibraryFile, NULL, PAGE_READONLY, 0, 0, NULL
.if eax != NULL
mov g_hLibraryMapping, eax
invoke MapViewOfFile, g_hLibraryMapping, FILE_MAP_READ, 0, 0, 0
.if eax != NULL
mov g_pLibraryImage, eax
inc ebx ; set flag OK
.endif
.endif
.endif
.if ebx == FALSE
invoke CloseLibrary
.endif
return ebx
ret
OpenLibrary endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; FindAtBackward
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
FindAtBackward proc pString:LPSTR
; returns zero-based position of '@'
option PROLOGUE:NONE
option EPILOGUE:NONE
Fix It may be buggy if @ symbol is first character and symbol name contains no more @ chars
invoke fstrlen, [esp+4]
mov edx, [esp+4]
mov cl, '@'
.while eax
dec eax
.break .if byte ptr [edx][eax] == cl
.endw
; .if ZERO?
; inc eax ; '@' found
; .endif
ret (sizeof DWORD)
option PROLOGUE:PROLOGUEDEF
option EPILOGUE:EPILOGUEDEF
FindAtBackward endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; IsNullImport
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IsNullImport proc pSymbol:LPSTR
option PROLOGUE:NONE
option EPILOGUE:NONE
Fix InString strstr
; assume eax:SDWORD
mov eax, [esp+4]
invoke InString, 1, eax, $CTA0("NULL_THUNK_DATA")
.if sdword ptr eax > 0
ret (sizeof DWORD)
.endif
mov eax, [esp+4]
invoke InString, 1, eax, $CTA0("IMPORT_DESCRIPTOR")
.if sdword ptr eax > 0
ret (sizeof DWORD)
.endif
; assume eax:nothing
;Fix
; .if $invoke(InString, 1, pSymbol, $CTA0("NULL_IMPORT_DESCRIPTOR"))
; inc ebx
; .endif
xor eax, eax
ret (sizeof DWORD)
option PROLOGUE:PROLOGUEDEF
option EPILOGUE:EPILOGUEDEF
IsNullImport endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; ConvertNumOfParamsFromSymbol
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ConvertNumOfParamsFromSymbol proc uses esi ebx pszSymbolName:LPSTR
; Returns number of parameters for this symbol or -1 if error
local acMessage[512]:CHAR
or ebx, -1 ; assume error
mov esi, pszSymbolName
invoke FindAtBackward, esi
.if eax
add eax, esi
inc eax
invoke atodw, eax
; mov ecx, eax
; and ecx, 011y
.if !(eax & 011y) ; is argument count is not devisible by 4 ?
shr eax, 2 ; /sizeof arg = num of params
.if eax < MAX_NUM_OF_PARAMS
mov ebx, eax
IFDEF DEBUG
.else
; Too many params
invoke wsprintf, addr g_acDebugMessage, $CTA0("\nWarning: Too many params %s\n\n"), esi
invoke PrintConsole, addr g_acDebugMessage, 0
ENDIF
.endif
.else
invoke wsprintf, addr acMessage, addr g_szArgCountNotDivBy4, esi
invoke PrintConsole, addr acMessage, 0
.endif
.endif
mov eax, ebx
ret
ConvertNumOfParamsFromSymbol endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; GetImportType
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
GetImportType proc pMemberHeader:PTR IMAGE_ARCHIVE_MEMBER_HEADER
option PROLOGUE:NONE
option EPILOGUE:NONE
; see 8.2. Import Type of Microsoft PExecutable and COFF Specification
or eax, -1 ; assume error
mov ecx, [esp+4]
add ecx, sizeof IMAGE_ARCHIVE_MEMBER_HEADER ; eax -> IMPORT_OBJECT_HEADER
.if word ptr [ecx] == IMAGE_FILE_MACHINE_UNKNOWN ; Sig1 Must be IMAGE_FILE_MACHINE_UNKNOWN.
; See Section 3.3.1, "Machine Types, " for more information.
.if word ptr [ecx+2] == 0FFFFh ; Sig2 Must be 0xFFFF.
movzx eax, (IMPORT_OBJECT_HEADER PTR [ecx]).rImport
; ImportRec RECORD Reserved:11, NameType:3, Type2:2
and eax, mask Type2 ; return Type
.endif
.endif
ret (sizeof DWORD)
option PROLOGUE:PROLOGUEDEF
option EPILOGUE:EPILOGUEDEF
GetImportType endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; GetImportNameType
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
GetImportNameType proc pMemberHeader:PTR IMAGE_ARCHIVE_MEMBER_HEADER
option PROLOGUE:NONE
option EPILOGUE:NONE
; see 8.3. Import Name Type of Microsoft PExecutable and COFF Specification
or eax, -1 ; assume error
mov ecx, [esp+4]
add ecx, sizeof IMAGE_ARCHIVE_MEMBER_HEADER ; eax -> IMPORT_OBJECT_HEADER
.if word ptr [ecx] == IMAGE_FILE_MACHINE_UNKNOWN ; Sig1 Must be IMAGE_FILE_MACHINE_UNKNOWN.
; See Section 3.3.1, "Machine Types, " for more information.
.if word ptr [ecx+2] == 0FFFFh ; Sig2 Must be 0xFFFF.
movzx eax, (IMPORT_OBJECT_HEADER PTR [ecx]).rImport
; ImportRec RECORD Reserved:11, NameType:3, Type2:2
and eax, mask NameType
shr eax, 2 ; return NameType
.endif
.endif
ret (sizeof DWORD)
option PROLOGUE:PROLOGUEDEF
option EPILOGUE:EPILOGUEDEF
GetImportNameType endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; FillSymEntries
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
FillSymEntries proc uses ebx esi edi p2ndLinkerMember:LPVOID, pLibraryArrayOfSymbols:LPVOID, uNumberOfSymbols:UINT
local fOk:BOOL
local dwSymFlags:DWORD
local uNumberOfMembers:UINT
local paOffsetsToMembers:LPVOID
local paIndices:LPVOID
local dwCcType:DWORD
local uNumberOfParameters:UINT
local uAtPosition:UINT ; from the beginning of the string
local ccUndecSymbolNameLength:UINT
local pUndecSymbolNameStart:LPSTR
local uIndex:UINT
local pMemberHeader:LPVOID ; PTR IMAGE_ARCHIVE_MEMBER_HEADER
local byImportType:BYTE ; IMPORT_CODE, IMPORT_DATA, IMPORT_CONST
local byImportNameType:BYTE ; IMPORT_ORDINAL, IMPORT_NAME, IMPORT_NAME_NOPREFIX, IMPORT_NAME_UNDECORATE
; Walks through String Table pointed by pLibraryArrayOfSymbols.
; String Table is a series of null-terminated strings that name all the symbols in the directory.
; Each string begins immediately after the null byte in the previous string.
; So we walks through it trying recognize the calling conversion of each symbol
; And we fill SYM_ENTRYs
and fOk, 0 ; clear flag OK
mov eax, p2ndLinkerMember
push dword ptr [eax]
pop uNumberOfMembers
add eax, 4 ; skip m = Number of Members
mov paOffsetsToMembers, eax ; paOffsetsToMembers points to the first member address
mov ecx, uNumberOfMembers
shl ecx, 2 ; sizeof pointer
add eax, ecx ; eax -> Number of Symbols
add eax, 4 ; skip m = Number of Symbols
mov paIndices, eax
_try
mov esi, pLibraryArrayOfSymbols
assume esi:ptr CHAR
lea edi, g_paCcEntries
assume edi:ptr CC_ENTRY
xor ebx, ebx
.while ebx < uNumberOfSymbols
; Skip _IMPORT_DESCRIPTOR_XXX, _NULL_IMPORT_DESCRIPTOR, XXX_NULL_THUNK_DATA etc...
.if $invoke(IsNullImport, esi)
IFDEF DEBUG
mov dwCcType, CC_WEIRD
invoke wsprintf, addr g_acDebugMessage, $CTA0("Skip: %s\n"), esi
invoke PrintConsole, addr g_acDebugMessage, 0
ENDIF
jmp @F
.endif
Fix May be init dwCcType with CC_WEIRD
or dwCcType, -1 ; init calling convention type
and dwSymFlags, 0 ; reset
or uNumberOfParameters, -1 ; reset to not recognized
and ccUndecSymbolNameLength, 0 ; init with 0
and pUndecSymbolNameStart, NULL
; or dwImportType, 0 ; init with IMPORT_CODE
mov ecx, ebx
shl ecx, 1 ; * sizeof Indice
add ecx, paIndices
movzx ecx, word ptr [ecx]
mov uIndex, ecx
; VA to symbol's IMAGE_ARCHIVE_MEMBER_HEADER
dec ecx ; make it zero-based
shl ecx, 2 ; * sizeof pointer
add ecx, paOffsetsToMembers
mov ecx, [ecx]
add ecx, g_pLibraryImage
mov pMemberHeader, ecx
invoke GetImportType, pMemberHeader
mov byImportType, al
.if ( eax == IMPORT_OBJECT_DATA ) || ( eax == IMPORT_OBJECT_CONST )
or dwSymFlags, FF_SYM_VARIABLE
.endif
invoke GetImportNameType, pMemberHeader
mov byImportNameType, al
invoke InString, 1, esi, addr g_sz__imp_
.if eax == 1
or dwSymFlags, FF_SYM___IMP_
add esi, sizeof g_sz__imp_ - 1 ; skip '__imp_'
.endif
invoke ConvertNumOfParamsFromSymbol, esi
mov uNumberOfParameters, eax
.if [esi] == '@' ; is it fastcall here ?
invoke FindAtBackward, esi
.if eax
mov ecx, eax
dec eax
mov ccUndecSymbolNameLength, eax
mov eax, esi
inc eax
mov pUndecSymbolNameStart, eax
mov dwCcType, CC_FASTCALL
IFDEF DEBUG
.else
mov dwCcType, CC_WEIRD
ENDIF
.endif
.elseif [esi] == '_' ; is it stdcall or cdecl here ?
invoke FindAtBackward, esi
mov uAtPosition, eax
.if eax
; stdcall here
mov ecx, eax
dec eax
mov ccUndecSymbolNameLength, eax
mov dwCcType, CC_STDCALL
.else
; cdecl here
invoke fstrlen, esi
dec eax
mov ccUndecSymbolNameLength, eax
mov dwCcType, CC_CDECL
comment ^
g_NumOfVariables
; cdecl here
; les't decide is it a function or exported variable
mov eax, pOffsets
mov edx, ebx
shl edx, 2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -