ã¯ããã«
åºç¤æè¡ç 究室ãªãµã¼ãã¨ã³ã¸ãã¢ã®ä¸å·ã§ããããã°ã·ã¹ãã ç§»è¡å¾è¨å¿µãã¹ã(?)第 1 åãæ å½ãã¾ãã
ä»å㯠FFRI Dataset 使ã«ããã£ã¦ãå©ç¨ãã¦ãã LIEF ã¨ããã©ã¤ãã©ãªã«ã¤ãã¦ç´¹ä»ãã¾ãã
LIEF 㯠PEã»ELF ãªã©ã®å®è¡ãã¡ã¤ã«ããã¼ã¹ããä¸é¨ã®ã¬ã³ã¼ãã®ç·¨éãè¡ãããã®ã©ã¤ãã©ãªã§ãã以ä¸ã®ãããªç¹å¾´ãåãã¦ãã¾ãã
- å®è¡ãã¡ã¤ã«ã®ä¸é¨ã®ã¬ã³ã¼ããç·¨éããä¸ã§æ°ããå®è¡ãã¡ã¤ã«ã¨ãã¦æ¸ãåºã
- ãã¼ã¹å¯è½ãªå®è¡ãã¡ã¤ã«ãã©ã¼ããããåç´ã«å¤ã (PE ELF MachO DEX VDEX ART ãªã©)
- C C++ Python ã§ã® API ãæä¾ (â» C ã®å ´åã¯ä¸é¨å©ç¨ã§ããªã API ãã)
å®è¡ãã¡ã¤ã«ã®ãã¼ãµã¼èªä½ã¯ pefile ã pyelftools ãããã¾ããããè¤æ°ã®å®è¡ãã¡ã¤ã«ãã©ã¼ãããã«å¯¾å¿ãããã¤ã¬ã³ã¼ãã®ç·¨éã¾ã§ã§ããã©ã¤ãã©ãªã¯ããã¾ã§ãªãã£ãããã«æãã¾ããGitHub ã¹ã¿ã¼æ°ã 1800 ã¨å¤ã注ç®ãéãã¦ãã¾ãã
åé ã§ã触ãã¾ããããFFRI Dataset ã§ã PE ãã¡ã¤ã«ã®è¡¨å±¤æ å ±åå¾ã« LIEF ãç¨ãã¦ãã¾ããã¾ããEndgame ãæä¾ãããã¼ã¿ã»ãã EMBER ã§ã PE ãã¡ã¤ã«ã®è¡¨å±¤æ å ±åå¾ã« LIEF ãç¨ãããã¦ãã¾ããããã¾ã§ã®ããã¡ã¯ãçåå¨ã ã£ã pefile ã¨å ±ã«æè¿ä½¿ãããããã«ãªã£ãå°è±¡ã§ãã
ç§ã¯å¾®åãªããã³ã³ããªãã¥ã¼ã¿ã¨ã㦠LIEF ã®éçºã«åå ãã¦ããã¾ãã¦ãPE ãã¡ã¤ã«ã®ãã¼ã¹å¦çã®ãã°ä¿®æ£ãè¡ãã¾ãããä»ã¯æ°è¦æ©è½ã®éçº(ãã¼ã¹å¯è½ãªãªã½ã¼ã¹ã®ç¨®é¡ã®å¢å )ã»ã©ã¤ãã©ãªã®å®å®æ§åä¸(ç ´æãã PE ãã¡ã¤ã«ã®ãã¼ã¹ãå¯è½ã«ãã)ã«åãçµãã§ãã¾ãã
æ¬è¨äºã§ã¯å ·ä½ä¾ãæããªãã LIEF ã®ãã¼ã¹æ©è½ (ç¹ã«ãç¹å¾´çãªãªã½ã¼ã¹å¨ããä¸å¿ã«)ã»ãã¤ããªç·¨éæ©è½ã«ã¤ãã¦ç´¹ä»ãã¾ãã
LIEF ã®ã¤ã³ã¹ãã¼ã«
ã¾ã LIEF ãã¤ã³ã¹ãã¼ã«ãã¾ãããã
$ git clone https://github.com/lief-project/LIEF.git $ cd LIEF && mkdir build && cd build $ cmake -DLIEF_PYTHON_API=on -DPYTHON_VERSION=3.6 -DCMAKE_BUILD_TYPE=Release -DLIEF_TESTS=on -GNinja .. $ ninja
ãã«ãçµäºå¾ build/api/python ã« cd ã㦠python (3.6 ç³»ãå¿
è¦) ãèµ·åãã¾ãã
$ python3 >>> import lief >>> print(lief.__version__) 0.11.0-ddc8b72
ä¸è¨ã®ããã«åºåãããã° OK ã§ãã
ãã¼ãµã¼ã¨ãã¦ã®ä½¿ãæ¹
æå§ãã«ãé©å½ã« PE ãã¡ã¤ã«ããã¼ã¹ãã¦ç¨®ã
ã®ã¬ã³ã¼ããåãåºãã¦ã¿ã¾ãããããªã½ã¼ã¹ã»ç½²åæ
å ±ã»ãããã°æ
å ±ãªã©ãå«ãã§ãã explorer.exe ã対象ã«ãã¾ãã
import lief binary = lief.parse("explorer.exe")
lief.parse ã§å®è¡ãã¡ã¤ã«ã®ãã¡ã¤ã«ã¿ã¤ããæ¨å®ã®ä¸ãé©åãªãã¼ãµã¼ã鏿ããã¼ã¹çµæãè¿ãã¦ããã¾ãããã® binary ã¨ãããªãã¸ã§ã¯ã㯠lief.PE.Binary ã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ã§ããã¼ã¹çµæã䏿¬ãã¦å«ã¾ãã¦ãã¾ãã試ãã« section headerã»signature ã®æ
å ±ãåºåãã¦ã¿ã¾ãã
# binary ã¯ã©ã¹ã®åã表示 print(type(binary)) # <class 'lief.PE.Binary'> # section header ã表示 for section in binary.sections: print(section) # .text 240b19 1000 240c00 400 0 6.35507 CNT_CODE - MEM_EXECUTE - MEM_READ # .imrsiv 4 242000 0 0 0 -0 CNT_UNINITIALIZED_DATA - MEM_READ - MEM_WRITE # .rdata a4df6 243000 a4e00 241000 0 4.78998 CNT_INITIALIZED_DATA - MEM_READ # .data 6084 2e8000 2a00 2e5e00 0 3.15808 CNT_INITIALIZED_DATA - MEM_READ - MEM_WRITE # .pdata 1b858 2ef000 1ba00 2e8800 0 6.25607 CNT_INITIALIZED_DATA - MEM_READ # .didat 828 30b000 a00 304200 0 3.2932 CNT_INITIALIZED_DATA - MEM_READ - MEM_WRITE # .rsrc 131818 30c000 131a00 304c00 0 4.94062 CNT_INITIALIZED_DATA - MEM_READ # .reloc 4d98 43e000 4e00 436600 0 5.45348 CNT_INITIALIZED_DATA - MEM_DISCARDABLE - MEM_READ # explorer.exe ã«å«ã¾ãã¦ããç½²åã表示 print(binary.signature) # Version: 1 # Digest Algorithm: SHA_256 # Content Info # ============ # Content Type: SPC_INDIRECT_DATA_CONTEXT # Type: SPC_PE_IMAGE_DATA # Digest Algorithm: SHA_256 # # # Certificates # ============ # Version: 3 # Serial Number: 33:00:00:02:66:bd:15:80:ef:a7:5c:d6:d3:00:00:00:00:02:66 # Signature Algorithm: SHA256_WITH_RSA_ENCRYPTION # Valid from: 2020-3-4 18:30:39 # Valid to: 2021-3-3 18:30:39 # Issuer: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Windows Production PCA 2011 # ... (çç¥)
ä»ã«ã©ããã£ãæ
å ±ããã¼ã¹ããã¦ããã®ãã¯ãJSON å½¢å¼ã§ lief.PE.Binary ãã·ãªã¢ã©ã¤ãºãã¦ããã lief.to_json ã®åºåçµæãã確èªãããã¨ãã§ãã¾ãã
print(lief.to_json(binary))
åºå
{ "data_directories": [ { "RVA": 0, "size": 0, "type": "EXPORT_TABLE" }, { "RVA": 3010088, "section": ".rdata", "size": 2640, "type": "IMPORT_TABLE" }, { "RVA": 3194880, "section": ".rsrc", "size": 1251352, "type": "RESOURCE_TABLE" }, { "RVA": 3076096, "section": ".pdata", "size": 112728, "type": "EXCEPTION_TABLE" }, { "RVA": 4436992, "section": ".rsrc", "size": 47704, "type": "CERTIFICATE_TABLE" }, { "RVA": 4448256, "section": ".reloc", "size": 19864, "type": "BASE_RELOCATION_TABLE" }, { "RVA": 2657520, "section": ".rdata", "size": 84, "type": "DEBUG" }, { "RVA": 0, "size": 0, "type": "ARCHITECTURE" }, { "RVA": 0, "size": 0, "type": "GLOBAL_PTR" }, { "RVA": 2417712, "section": ".rdata", "size": 40, "type": "TLS_TABLE" }, { "RVA": 2414480, "section": ".rdata", "size": 280, "type": "LOAD_CONFIG_TABLE" }, { "RVA": 0, "size": 0, "type": "BOUND_IMPORT" }, { "RVA": 2570672, "section": ".rdata", "size": 9112, "type": "IAT" }, { "RVA": 3000136, "section": ".rdata", "size": 1696, "type": "DELAY_IMPORT_DESCRIPTOR" }, { "RVA": 0, "size": 0, "type": "CLR_RUNTIME_HEADER" } ], "debug": [ { "addressof_rawdata": 2839664, "characteristics": 0, "code_view": { "age": 1, "cv_signature": "PDB_70", "filename": "explorer.pdb", ...(çç¥) }
ãªããªãæ å ±éãå¤ãã§ããã(å®ã¯ããã§ãã»ãã®ä¸é¨ã§ããã®å¾åé ç½®æ å ±ã®ã¨ã³ããªã¼ã大éã«ç¶ãã¾ãã) DOS Headerã»NT Headerã»Optional Headerã»Section Headerã»COFF ãããã°æ å ±ã»åé ç½®æ å ±ã»ãªã½ã¼ã¹ãªã©ãPE 表層æ å ±ã®ããªãã®é¨åãå«ã¾ãã¦ãã¾ãã
lief.to_json ã®çµæã«å«ã¾ããã¬ã³ã¼ãã®å
¨è²ãç¥ãããæ¹ã¯ãFFRI Dataset ã® JSON Schema ãã覧ãã ãããåã¬ã³ã¼ãã®èª¬æã description ã¨ãã¦ã¤ããé©å® MSDN ã¸ã®ãªã³ã¯ãä»ä¸ãã¦ãã¾ãã®ã§ãPE ãã¡ã¤ã«ã®åå¼·ã«ããªããã¨æãã¾ãã
resources 㨠resources_manager
大æµã®æ
å ±ã¯ lief.PE.Binary ã®ããããã£ã¨ãã¦ç°¡åã«ã¢ã¯ã»ã¹ã§ãã¾ããããªã½ã¼ã¹ã«ã¤ãã¦ã¯å°ãç¹æ®ã§ãã
åºæ¬çã«ã¯ resources ããããã£ã® childs ã«ã¢ã¯ã»ã¹ããæ¬²ãããªã½ã¼ã¹ id ãæã£ããã¼ããæ¢ç´¢ããæ¹æ³ãã¨ãã¾ããä¾ãã°ãå®è¡ãã¡ã¤ã«ã«å«ã¾ãããããã§ã¹ããå¾ããã¨æã£ãå ´åã
root = binary.resources for child in root.childs: if child.id == int(lief.PE.RESOURCE_TYPES.MANIFEST): manifest = bytes(child.childs[0].childs[0].content).decode("utf-8") print(manifest)
ã®ããã« resources.childs ãã辿ããæ¬²ãããã¼ã¿ãã¼ããæ¢ç´¢ãã¾ãã
â»å°ãã ãããã§ãªã½ã¼ã¹ã®ãã¼ã¿æ§é ã«ã¤ãã¦ç°¡åã«èª¬æãã¦ããã¾ãããªã½ã¼ã¹ã¯æ¨æ§é ã«ãªã£ã¦ãããåãã¼ãã¯çãã¼ã¿ (icon string manifest ãªã©) ãããã¯ãsubtree ã¸ã®ãã¤ã³ã¿ãå«ã¾ãã¦ãã¾ããLIEF ã§ã¯åè
ã ResourceData å¾è
ã ResourceDirectory ã¯ã©ã¹ã§ç®¡çãã¦ãããleaf ã«ã¯å¿
ã ResourceData ãæ¥ãããã«ãªã£ã¦ãã¾ããæ¨æ§é ã®åé層ã«ã¯ç¹å¥ãªæå³ããããå³ 1 ãè¦ã¦ããããã°ããããããã§ãããroot ã第 0 é層ã¨ãã¦å®ç¾©ããå ´åã
- 第 1 é層ã¯ãªã½ã¼ã¹ã®ã¿ã¤ã
- 第 2 é層ã¯å«ã¾ãããªã½ã¼ã¹ã® ID
- 第 3 é層ã¯è¨èªæ å ±
ãæã£ã¦ãããé層ã«ãã£ã¦çãã¼ã¿ãã°ã«ã¼ãã³ã°ããã¦ãã¾ãã
binary.resources ã§ã¯ãã®æ¨æ§é ãæã£ããã¼ã¿ããã®ã¾ã¾è¿ããããå¿
è¦ãªãªã½ã¼ã¹ãåå¾ããã«ã¯æ¨æ§é ãæ¢ç´¢ããå¿
è¦ããããå°ãã ãé¢åã§ãããã®æéãçããããLIEF ã§ã¯ resources_manager ããããã£ãç¨æããã¦ãã¾ããããã使ãã¨å¿
è¦ãªãªã½ã¼ã¹ã¸ã®æ¢ç´¢å¦çã resources_manager ã«å§è¨ãããã¨ãã§ãã以ä¸ã®ããã«ã·ã³ãã«ã«å¿
è¦ãªãã¼ã¿ã«ã¢ã¯ã»ã¹ãããã¨ãå¯è½ã§ãã
print(binary.resources_manager.manifest)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n<!-- Copyright (c) Microsoft Corporation -->\r\n<!--\r\n This is the manifest file only for Explorer.\r\n It only differs from windowsshell.manifest in the <dpiAware> tag.\r\n-->\r\n<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">\r\n<assemblyIdentity\r\n name="Microsoft.Windows.pcshellshell.explorer"\r\n ... (çç¥)
ã¾ããresources_manager ãä»ãã¦ã¢ã¯ã»ã¹ããã¨ããªã½ã¼ã¹ã¿ã¤ãã«å¿ã ResourceData ã«å«ã¾ãã¦ãããã¼ã¿ã®ãã¼ã¹ãå¯è½ã§ããã°ããããåããã¦è¡ã£ã¦ããã¾ããä¾ãã°ãã¼ã¸ã§ã³æ
å ±ã« resources_manager ãçµç±ãã¦ã¢ã¯ã»ã¹ããã¨
ver = binary.resources_manager.version print(type(ver)) # <class 'lief.PE.ResourceVersion'> print(ver.fixed_file_info) # Signature: feef04bd # Struct version: 10000 # File version: 10 - 0 - 19041 - 329 # Product version: 10 - 0 - 19041 - 329 # File OS: NT_WINDOWS32 # File type: APP
ã®ããã«ãResourceVersion ã¨ãããã¼ã¸ã§ã³æ
å ±ãä¿æããå°ç¨ã®ã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ãçµæã¨ãã¦è¿ãã¦ããã¾ãããã®ç¹ãresources ã使ãå ´åããªã½ã¼ã¹ã®çã®ãã¤ãåã®ãã¼ã¿ã«ããã¢ã¯ã»ã¹ã§ãããåçã®æ
å ±ã«ã¢ã¯ã»ã¹ããã«ã¯ããã®ãã¤ãåãå度ãã¼ã¹ããªããã°ããã¾ããã
ããã¾ã§èãã¨ãã常㫠resources_manager ã使ãã°ããã®ã§ã¯?ãã¨æããããããã¾ããããresources ããããã£ãå¿
è¦ã«ãªãå ´é¢ããã¡ããããã¾ãã
ç¹ã«ãã«ã¦ã§ã¢ã«å¤ãã§ãããã¢ã¤ã³ã³ããã¤ã¢ãã°ã®ãªã½ã¼ã¹ã®ä¸ã«ããã¯ãããã¼ã¿ãåãè¾¼ãã§ããå ´åãããã¾ãããã®ã±ã¼ã¹ã§ã¯ãresources_manager ã使ãã¨ãã¼ã¿ãã¢ã¤ã³ã³ã»ãã¤ã¢ãã°ãªã©ã¨ãã¦è§£éã§ããªããããresources_manager çµç±ã§ã¢ã¯ã»ã¹ãããã¨ããã¨ããã¼ã¹éç¨ã§ã¯ã©ãã·ã¥ãã¢ã¯ã»ã¹ãããã¨ãã§ãã¾ãããä¾ãã°ã§ããããã¡ãã®æ¤ä½(VirusTotal ã¸ã®ãªã³ã¯ ãªãããã®å®è¡ãã¡ã¤ã«ã¯ãã«ã¦ã§ã¢ã§ãã®ã§ãä»®æ³ç°å¢ã§ã®ä½æ¥ãæ¨å¥¨)ã®å ´åãVirusTotal ã«ããã°ãªã½ã¼ã¹ã¨ãã¦ã¢ã¤ã³ã³ãå«ãã§ãããã¨ããããã¾ãã(å³ 2)ãresources_manager çµç±ã§ã¯ã¢ã¯ã»ã¹ã§ãã¾ããã
binary = lief.PE.parse("95eb631f665e10e4214093a3104ae217da049640a1d961a907bae712be5f10c1") binary.resources_manager.icons # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # lief.corrupted: Group icon type should be equal to 1 (5147) # â ã¢ã¤ã³ã³ã¨ãã¦è§£éã§ããªããã¼ã¿ã§ãããããã¼ã¹ã®éä¸ã§ã¯ã©ãã·ã¥ãã¦ãã¾ã
VirusTotal ã® Details ãè¦ãã¨ãã¢ã¤ã³ã³ã®ãã¼ã¿ãå«ã¾ãã¦ãã¾ããã7.88 ã¨é常ã«é«ãã¨ã³ãããã¼ã«ãªã£ã¦ãããããã¯ãããã¼ã¿ãå«ã¾ãã¦ãã¾ãããããã£ãå ´åã«ã¯ resources ããã¢ã¯ã»ã¹ããããã¼ã¿ã¾ã§è¾¿ã£ã¦ãããªããã°ããã¾ããã
å°ãé·ããªãã¾ããã®ã§ãresources ããããã£ã¨ resources_manager ããããã£ã®éãã«ã¤ãã¦ç°¡åã«ã¾ã¨ãã¦ããã¾ãã
resourcesãããã㣠-> ãªã½ã¼ã¹ã®çãã¼ã¿ã«ã¢ã¯ã»ã¹ããéã«ç¨ããããªã½ã¼ã¹ã®æ¨æ§é ããã®ã¾ã¾ä¿æãã¦ããã®ã§ãå¿ è¦ãªãã¼ã¿ã«ã¢ã¯ã»ã¹ããã«ã¯æ¯åº¦æåã§æ¢ç´¢ãè¡ãå¿ è¦ããããresources_managerãããã㣠-> ãªã½ã¼ã¹ãã¿ã¤ããã¨ã«ãã¼ã¹ããçµæãåå¾ããéã«ç¨ãã(ãã ãããã¼ã¹ã§ããªãå ´åãçµæã®åå¾ä¸å¯)ãæ¢ç´¢ã¯resources_managerã®ä¸ã§è¡ãªã£ã¦ãããã¦ã¼ã¶ã¼ãæåã§è¡ãå¿ è¦ã¯ãªãã
ã¡ãªã¿ã« lief.to_json ã«ã¯ resources 㨠resources_manager ã®ä¸¡æ¹ãåºåçµæã«å«ã¾ãã¦ããããããã resources_tree resources_manager ããã¼ã¨ãã¦åãåºããã¨ãå¯è½ã§ãã
ãã¤ããªç·¨éãã¼ã«ã¨ãã¦ã® LIEF
ããã¾ã§ãLIEF ã®ãã¼ãµã¼ã¨ãã¦ã®å´é¢ã«ã¤ãã¦ç´¹ä»ãã¦ãã¾ããããLIEF ã¯ãã¼ã¹çµæã®ä¸é¨ã®ã¬ã³ã¼ããç·¨éãæ°ããå®è¡ãã¡ã¤ã«ã¨ãã¦æ¸ãåºãæ©è½ãæãã¦ãã¾ãããã®æ©è½ã«ã¤ãã¦ãå ·ä½ä¾ãæããªããç´¹ä»ãã¦ããã¾ãã
ãªããå ¬å¼ã§ããã®æ©è½ã使ã£ããµã³ãã«ãç¨æããã¦ããããªãã¸ããªã¨ãã¦ã¾ã¨ãããã¦ããã®ã§ãèå³ãããã°ãã¡ããåããã¦ã覧ãã ããã(ç¹ã« PE from scratch ã¨ãã PE ãã¡ã¤ã«ã 0 ããä½ããµã³ãã«ã¹ã¯ãªããã¯é常ã«è峿·±ããµã³ãã«ã§ãã)
ä¾ 1: IMAGE_DATA_DIRECTORY ã® RVA å¤ã®ç·¨é
Optional Header ã«å«ã¾ãã IMAGE_DATA_DIRECTORY ã®ã¬ã³ã¼ãã® 1 ã¤ãç·¨éããæ°ããå®è¡ãã¡ã¤ã«ã¨ãã¦æ¸ãåºãã¦ã¿ã¾ãããã(使 ãã®ãããªãã¨ãããã®ãã®çç±ã¯å¾è¿°ãã¾ãã) ãã¹ãç¨ã«ä»¥ä¸ã®ãã㪠C ã®ã½ã¼ã¹ã³ã¼ã
#include <windows.h> int main() { MessageBoxA(NULL, "Stand by ready", "MBCS", MB_OK); }
ã MSVC ã§ã³ã³ãã¤ã«ãããã®ãå©ç¨ãã¾ããx64 ã§ãããã°ã¨ã³ããªã¼ãæ¶ãããªãã³ã³ãã¤ã«ãªãã·ã§ã³ã§ãã«ããããã¡ã¤ã«å㯠test0.exe ã¨ãã¦ããã¾ãã
ç·¨éåã® IMAGE_DATA_DIRECTORY ã®é åã表示ãã¦ããã¾ãã
import lief binary = lief.PE.parse("test0.exe") print(binary.data_directories) for data_directory in binary.data_directories: if data_directory.rva != 0: print(data_directory)
# åºåçµæ Data directory "IMPORT_TABLE" RVA: 0x 26fc Size: 0x b4 Section: .rdata Data directory "EXCEPTION_TABLE" RVA: 0x 4000 Size: 0x 168 Section: .pdata Data directory "BASE_RELOCATION_TABLE" RVA: 0x 5000 Size: 0x 28 Section: .reloc Data directory "DEBUG" RVA: 0x 2258 Size: 0x 38 Section: .rdata Data directory "LOAD_CONFIG_TABLE" RVA: 0x 2290 Size: 0x 130 Section: .rdata Data directory "IAT" RVA: 0x 2000 Size: 0x 198 Section: .rdata
ãã® binary ãã IMAGE_DATA_DIRECTORY ã®ã¨ã³ããªã¼ã®ãã¡ IMAGE_DATA_DIRECTORY_ENTRY_DEBUG ãåãåºããRVA ã 0 以å¤ã®ç¡å¹ãªå¤ (0xffffffff) ã«è¨å®ããtest0_mod.exe ã¨ãã¦æ¸ãåºãã¾ããbinary.data_directories ã®é
åã«ã¢ã¯ã»ã¹ããrva ããããã£ã®å¤ã 0xffffffff ã«è¨å®ãã¾ãã
binary = lief.PE.parse("test0.exe") binary.data_directories[int(lief.PE.DATA_DIRECTORY.DEBUG)].rva = 0xffffffff # <-- rva ã®å¤ã 0xffffffff ã«è¨å® print(binary.data_directories[int(lief.PE.DATA_DIRECTORY.DEBUG)]) # Data directory "DEBUG" # RVA: 0x ffffffff # <-- RVA ã 0xffffffff ã«ç¢ºãã«æ¸ãæãã£ã¦ãã # Size: 0x 38 # Section: .rdata
ãã®ãã¨ãå®è¡ãã¡ã¤ã«ã¨ãã¦æ¸ãåºãã«ã¯ãPE Builder ã¨ããã¯ã©ã¹ã使ããbuild ã¡ã½ãããå¼ã¶ãã¨ã«ããè¡ãã¾ãã
builder = lief.PE.Builder(binary) # <-- PE Builder ã¯ã©ã¹ä½æ builder.build() # <-- PE ãã¡ã¤ã«ããã«ã builder.write("test0_mod.exe") # <-- ãã¡ã¤ã«ã¨ãã¦æ¸ãåºã
test0_mod.exe ã§ããããããã°æ
å ±ãæ¹å¤ãã¦ããã ãã§ãåé¡ãªãå®è¡å¯è½ã§ãã
ãã¦ããã®æ¹å¤ã«ããä¸ä½ä½ãèµ·ããã®ã§ãããããå®ã¯ dumpbin.exe ã«ããéã¢ã»ã³ãã«ãã§ããªããã¦ãã¾ãã¾ã (å³ 3)ã
ãããã°ã»ã¨ãã¹ãã¼ãæ
å ±ãªã©ã«ã¤ãã¦ã¯ç¹ã«ããã§ããããã«ã¦ã§ã¢ã§ã¯ãã㦠RVA ããã®ããã« 0 以å¤ã®ç¡å¹ãªå¤ã«è¨å®ãã¦ããå ´åãããã¾ããpefile LIEF 㯠RVA ã«ç¡å¹ãªå¤ãè¨å®ããã¦ããå ´åããã®é
ç®ã«ã¤ãã¦ãã¼ã¹ã䏿ããã¼ã¿ã¨ã³ããªã¼ããªããã®ã¨å¤æãã¦ããã¾ããããã dumpbin.exe ã§ã¯ãã®è¾ºãã®æ¤è¨¼ããã¾ããã£ããã¨ã¯è¡ããã¦ããªãããã§ã表層æ
å ±ãåºåãã¦ããã¾ããã
ä¾ 2: import table ã«æ°ããã¨ã³ããªã¼ã追å
åã®ä¾ã¯æ£ç´ binary editor ã§ãç°¡åã«ã§ãã¦ãã¾ãä¾ã§ããã®ã§ã次㯠LIEF ã使ããªãã¨å®ç¾ãã«ããä¾ã«ã¤ãã¦ã¿ã¦ããã¾ãã
#include <stdio.h> int main() { puts("Hello World"); }
ä¸è¨ãã¡ã¤ã«ã MSVC ã§ãã«ãããå®è¡ãã¡ã¤ã«åã test1.exe ã«ãã¦ããã¾ããä»å㯠test1.exe ã«å®è¡æã«ã¯ä½¿ãããªã dummy import 颿°ã追å ãã¦ã¿ã¾ãã
import lief binary = lief.PE.parse("test1.exe") binary.optional_header.dll_characteristics &= ~lief.PE.DLL_CHARACTERISTICS.DYNAMIC_BASE # <-- ASLR ãç¡å¹å user32 = binary.add_library("user32.dll") # <-- user32.dll!MessageBoxA ãã¤ã³ãã¼ãããããã«ã¤ã³ãã¼ããã¼ãã«ãç·¨é user32.add_entry("MessageBoxA") builder.build_imports(True).patch_imports(True) # <-- import table ãåæ§ç¯ builder.build() builder.write("test1_mod.exe")
â»ASLR ãç¡å¹ã«ãã¦ãã¾ããããã㯠LIEF ã®ç¾å¨ã®å®è£
ã®å¶ç´ã«ãããã®ã§å¿
é ã§ããbuild_imports ã®å®è£
ãè¦ãã¨ãããã¾ãããã¨ã³ããªã¼ã追å ããå¾ã«åé
ç½®æ
å ±ã®æ´æ°ãè¡ãªã£ã¦ããã¾ããããã®ãããimage base ã®å¤ãåºå®ãã¦ããå¿
è¦ãããã¾ãã
ç·¨éå¾ import table ã« user32.dll!MessageBoxA ã追å ããã¦ãããã¨ã確èªãã¦ã¿ã¾ãã
$ diff <(rabin2 -ij test1_mod.exe | jq ".imports[].name" | sort) <(rabin2 -ij test1.exe | jq ".imports[].name" | sort) < "user32.dll_MessageBoxA"
確ãã« user32.dll!MessageBoxA ã追å ããã¦ãããã¨ã確èªã§ãã¾ãããã¡ãããimport table ç·¨éå¾ã®ãã¡ã¤ã«ã¯å®è¡å¯è½ã§ã (å³ 4)ã
ãããã import table ã®ç·¨éã¯å ·ä½çã«ã©ãããå ´é¢ã§ä½¿ããã§ãããããã¾ããè§£æè ã«å©ç¨ãã¦ãã API æ å ±ã«ã¤ãã¦é¯è¦ããããã¨ãã§ãã¾ããã¾ããPE 表層æ å ±ãç¨ããæ©æ¢°å¦ç¿ã«ãããã«ã¦ã§ã¢æ¤ç¥ã§ import table ã®æ å ±ãå©ç¨ãã¦ããå ´åãæ¤ç¥åé¿ã«ãããã import table ã®ç·¨éã¯å©ç¨ãããã¨ãããã¾ããgym malwareãªã©ã¯æ©æ¢°å¦ç¿ã«ããéçæ¤ç¥åé¿ã«ããããPE ãã¡ã¤ã«ã®å種ã¨ã³ããªã¼ãç·¨éãã¾ãããç·¨éã® 1 ææ®µã¨ãã¦ãã® import table ã®æ¹å¤ãè¡ã£ã¦ãã¾ãã
ãããã«
æ¬è¨äºã§ã¯ LIEF ã®ãã¼ãµã¼ã»ãã¤ããªç·¨éã®æ©è½ã«ã¤ãã¦å ·ä½ä¾ãæããªããç´¹ä»ãã¾ãããä»å¾ãLIEF ãå©ç¨ããæ¹ã®ãå½¹ã«å°ãã§ããã¦ãã°å¹¸ãã§ãã
pefile 㨠LIEF ã両æ¹ä½¿ã£ã¦ããäººã®ææ³ã¨ãã¦ã¯ãLIEF ã¯(pefile ã¨æ¯è¼ããã¨)ã¾ã ã¾ã å®å®æ§ã«ããé£ãããã¨ããæãã§ããå°ãå¤ãã£ãããã«ã¼ã§ããã¯ããã¦ãããããã¨ã表層æ å ±å徿ã«ã»ã°ãã©ã§è½ã¡ãããã¡ã¢ãªä½¿ãæ½°ãã¦è½ã¡ãã¿ãããªãã¨ã¯ããããã¾ãã
䏿¹ã§ pefile ã¨æ¯è¼ãã㨠LIEF 㯠C/C++ ãã使ããã¨ããå©ç¹ãããã¾ããã¾ãããã¼ã¹ã§ãã¦ããæ å ±ã LIEF ã®æ¹ãå¤ããããã«å®è£ ã綺éºã§æ¡å¼µãããããªã£ã¦ãããå®å®æ§ãåä¸ããã°"æå¼·"ã®è¡¨å±¤æ å ±åå¾ãã¼ã«ã«ãªããã¨ã¯ééããªãã§ããä»å¾ã«æå¾ ã§ããã

