Для получения содержимого системной dll использую bat-файл Код (Text): ::стираю с экрана cls ::устанавливаю путь и имя файла set masm64_path=\masm64\ set filename=user32 %masm64_path%bin\dumpbin.exe /EXPORTS %windir%\System32\%filename%.dll /OUT:%filename%.txt содержимое user32.txt Код (Text): Dump of file C:\Windows\System32\user32.dll File Type: DLL Section contains the following exports for USER32.dll 00000000 characteristics 4CE799CD time date stamp Sat Nov 20 17:50:05 2010 0.00 version 1500 ordinal base 1003 number of functions 830 number of names ordinal hint RVA name 1502 0 000083C0 ActivateKeyboardLayout 1503 1 0002AD40 AddClipboardFormatListener 1504 2 000235B8 AdjustWindowRect 1505 3 00017CE4 AdjustWindowRectEx .... 2341 33C 0007B430 wvsprintfA 2342 33D 00020BFC wvsprintfW 1500 0002B260 [NONAME] 1501 0002AE80 [NONAME] .... Summary 2000 .data A000 .pdata 10000 .rdata 1000 .reloc 5B000 .rsrc 81000 .text Далее вручную создаю из user32.txt файлы user32.def и user32.inc содержимое user32.inc Код (Text): extern __imp_user32_ordinal1500:qword user32_ordinal1500 TEXTEQU <__imp_user32_ordinal1500> extern __imp_user32_ordinal1501:qword user32_ordinal1501 TEXTEQU <__imp_user32_ordinal1501> extern __imp_ActivateKeyboardLayout:qword ActivateKeyboardLayout TEXTEQU <__imp_ActivateKeyboardLayout> extern __imp_AddClipboardFormatListener:qword AddClipboardFormatListener TEXTEQU <__imp_AddClipboardFormatListener> extern __imp_AdjustWindowRect:qword AdjustWindowRect TEXTEQU <__imp_AdjustWindowRect> extern __imp_AdjustWindowRectEx:qword AdjustWindowRectEx TEXTEQU <__imp_AdjustWindowRectEx> extern __imp_AlignRects:qword ... содержимое user32.def Код (Text): EXPORTS user32_ordinal1500=ordinal1500 @1500 NONAME user32_ordinal1501=ordinal1501 @1501 NONAME ActivateKeyboardLayout=__imp_ActivateKeyboardLayout AddClipboardFormatListener=__imp_AddClipboardFormatListener AdjustWindowRect=__imp_AdjustWindowRect AdjustWindowRectEx=__imp_AdjustWindowRectEx .... далее при помощи bat Код (Text): set masm64_path=\masm64 set filename=user32 %masm64_path%\bin\link -lib /DEF:%filename%.def /OUT:%filename%.lib /MACHINE:X64 получаю user32.lib файл. Как автоматизировать ручную работу и всю рутину переложить на bat-файл? P.S. С удивлением обнаружил, что в kernel32.dll нет ExitProcess, а в user32.dll нет DefWindowProcA, обе функции портируются из ntdll.dll (RtlExitUserProcess и NtdllDefWindowProc_A соответственно)
bat-файл для создания user32.inc из user32.txt Код (Text): set FileName=user32 for /f "skip=16 tokens=1-4" %%a in (%FileName%.txt) do ( @echo extern __imp_%%d:qword >> %FileName%.inc @echo %%d TEXTEQU ^<__imp_%%d^> >> %FileName%.inc ) bat-файл для создания user32.def из user32.txt Код (Text): set FileName=user32 @echo EXPORTS >> %FileName%.def for /f "skip=16 tokens=1-4" %%a in (%FileName%.txt) do @echo %%d=__imp_%%d >> %FileName%.def skip=16 пропускаю первые 16 строк в user32.txt Код (Text): Dump of file C:\Windows\System32\user32.dll File Type: DLL Section contains the following exports for USER32.dll 00000000 characteristics 4CE799CD time date stamp Sat Nov 20 17:50:05 2010 0.00 version 1500 ordinal base 1003 number of functions 830 number of names ordinal hint RVA name 1502 0 000083C0 ActivateKeyboardLayout <-- полезная информация начинается здесь ^<__imp_%%d^> экранирую управляющие символы "<" и ">" чтобы bat-файл воспринимал их, как обычные символы. Правда, пока не получается из строк Код (Text): 1500 0002B260 [NONAME] создать строки в user32.def Код (Text): user32_ordinal1500=ordinal1500 @1500 NONAME и user32.inc Код (Text): extern __imp_user32_ordinal1500:qword user32_ordinal1500 TEXTEQU <__imp_user32_ordinal1500>
и, наконец, (барабанная дробь) inc_def.bat Код (Text): @echo off cls set masm64_path=\masm55\ set FileName=user32 %masm64_path%bin\dumpbin.exe /EXPORTS %windir%\System32\%FileName%.dll /OUT:%FileName%.txt @echo EXPORTS >> %FileName%.def for /f "skip=16 tokens=1-4" %%a in (%FileName%.txt) do ( if "%%a"=="Summary" exit if "%%d"=="" @echo extern __imp_%FileName%_ordinal%%a:qword >> %FileName%.inc if "%%d"=="" @echo %FileName%_ordinal%%a TEXTEQU ^<__imp_%FileName%_ordinal%%a^> >> %FileName%.inc if "%%d"=="" @echo %FileName%_ordinal%%a=ordinal%%a @%%a NONAME >> %FileName%.def if not "%%d"=="" @echo extern __imp_%%d:qword >> %FileName%.inc if not "%%d"=="" @echo %%d TEXTEQU ^<__imp_%%d^> >> %FileName%.inc if not "%%d"=="" @echo %%d=__imp_%%d >> %FileName%.def )
Код (Text): @echo off cls set masm64_path=\masm55\ set FileName=user32 if exist %FileName%.inc del %FileName%.inc if exist %FileName%.def del %FileName%.def %masm64_path%bin\dumpbin.exe /EXPORTS %windir%\System32\%FileName%.dll /OUT:%FileName%.txt @echo EXPORTS >> %FileName%.def for /f "skip=16 tokens=1-4" %%a in (%FileName%.txt) do ( if "%%a"=="Summary" goto :exit if "%%d"=="" ( @echo extern __imp_%FileName%_ordinal%%a:qword >> %FileName%.inc @echo %FileName%_ordinal%%a TEXTEQU ^<__imp_%FileName%_ordinal%%a^> >> %FileName%.inc @echo %FileName%_ordinal%%a=ordinal%%a @%%a NONAME >> %FileName%.def ) else ( if not "%%d"=="(forwarded" ( @echo extern __imp_%%d:qword >> %FileName%.inc @echo %%d TEXTEQU ^<__imp_%%d^> >> %FileName%.inc @echo %%d=__imp_%%d >> %FileName%.def ))) :exit %masm64_path%bin\link -lib /DEF:%FileName%.def /OUT:%FileName%.lib /MACHINE:X64
ну, для вашего счастья ) Код (C): import sys import os import argparse import pefile parser = argparse.ArgumentParser(description='INC to DEF script') parser.add_argument('-f', '--filename', type=str, help='file for analyze', required=True) parser.add_argument('-p', '--path', type=str, help='path to link', default="C:\\asm\\masm64\\bin") args = parser.parse_args() pathToLink = args.path fileName = args.filename cwd = os.getcwd() #current dir windir = os.environ["WINDIR"] dllFilePath = windir + "\\System32\\" + fileName + ".dll" pe = pefile.PE(dllFilePath) export_fn = [] for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols: if exp.name: if not exp.forwarder: export_fn.append([exp.ordinal, hex(exp.address), exp.name]) else: export_fn.append([exp.ordinal, hex(exp.address), "NONE"]) fileDef = open(cwd + '\\' + fileName + ".def", 'w') fileInc = open(cwd + '\\' + fileName + ".inc", 'w') fileDef.write("EXPORTS\n") for fn in export_fn: if fn[2] != "NONE": fileInc.write("extern __imp_"+fn[2]+":qword\n") fileInc.write(fn[2]+" TEXTEQU <__imp_"+fn[2]+">\n") fileDef.write(fn[2]+"=__imp_"+fn[2]+"\n") else: fileInc.write("extern __imp_"+fileName+"_ordinal"+str(fn[0])+":qword\n") fileInc.write(fileName+"_ordinal"+str(fn[0])+" TEXTEQU <__imp_"+fileName+"_ordinal"+str(fn[0])+">\n") fileDef.write(fileName+"_ordinal"+str(fn[0])+"=ordinal"+str(fn[0])+" @"+str(fn[0])+" NONAME\n") fileDef.close() fileInc.close() command = pathToLink+"\\link -lib /DEF:"+ fileName + ".def /OUT:" + fileName + ".lib /MACHINE:X64" os.system(command) exit(0) Пример вызова:
Ах, да, я забыл - путь к dumpbin уже не нужен в моем скрипте. Забыл убрать . Поправил - заменил на путь к link модулю. И добавил вызов создания lib файла.
Я тоже поиграться захотел. Вот: Код (Bash): #!/bin/bash tee >( echo "; $1" > $1.inc awk "$(cat <<-END NR>16 { if (match(\$3, /[NONAME]/,m)) { print "extern __imp_$1_ordinal" \$1 ":qword" print "$1_ordinal" \$1 " TEXTEQU <__imp_$1_ordinal" \$1 ">" } else { print "extern __imp_" \$4 ":qword" print \$4 " TEXTEQU <__imp_" \$4 ">" } } END )" >> $1.inc) >( echo EXPORTS > $1.def awk "$(cat <<-END NR>16 { if (match(\$3, /[NONAME]/,m)) { print "$1_ordinal" \$1 "=ordinal" \$1 " @" \$1 " NONAME" } else { print \$4 "=__imp_" \$4 } } END )" >> $1.def) > /dev/null Использовать: Код (Text): %masm64_path%bin\dumpbin.exe /EXPORTS %windir%\System32\%filename%.dll | ^ bash скриптвыше %filename% p.s. Все нужные тулзы идут сразу с гитом, так что