【逆向】OllyDbg中的UDD文件格式參考

起因:調試A程序有很多斷點、註釋之類的,後來A程序變動成B程序,體積也變化了,但是之前操作的地址沒有什麼變化,這個時候,UDD文件就不能用了,豈不是浪費xi gan?

提醒:以下結構是其中一部分,因爲用到了這些所以分析了這些,還有一些未標註的,大家可以自己對應。

PS:如上想重新使用A程序的UDD文件,只需要修改UDD文件的頭部幾個字段即可。 // 前提是 沒有ASLR類似操作

 



// 0x0A  可以作爲結束,也可以作爲Signature的一部分。 我分析的時候和別人不一樣。。。


DWORD 	dwSignature;			// Mod
DWORD	dwSize;				// data長度
BYTE 	byData[0x17];			// 長度 = 0x15 + '0'; 後邊有一個0A
BYTE 	byVerSignature[0x3];	// "Ver"
DWORD 	dwVerLength;			// Ver的長度
BYTE*	pbyVerBuffer;			// Ver的字符串(長度爲dwVerLength+1)

BYTE 	byFileSignature[0x3];	// "Fil"
DWORD 	dwFileLength;			// 文件路徑長度
BYTE* 	pbyFileName;			// 文件路徑字符串(長度爲dwFileLength+1)

BYTE 	bySizeSignature[0x3];	// "Siz"
DWORD 	dwSizeLength;			// Siz長度
BYTE* 	pbySizeBuffer;			// Siz內容(長度爲dwSizeLength+1)

BYTE 	byTstSignature[0x3];	// "Tst"
DWORD 	dwTstLength;			// Tst長度
BYTE* 	pbyTstBuffer;			// Tst內容(長度爲dwTstLength+1)

BYTE 	byCcrSignature[0x3];	// "Ccr"
DWORD 	dwCcrLength;			// Ccr長度
BYTE* 	pbyCcrBuffer;			// Ccr內容(長度爲dwCcrLength+1)

// 下面是若干個 "Us6" - 用戶自定義註釋
BYTE 	byUs6Signature[0x3];	// "Us6"
DWORD 	dwUs6Length;			// Us6長度
DWORD 	dwUs6Offset;			// 自定義註釋的偏移(需要加上基地址)
BYTE* 	pbyUs6Buffer;			// Us6內容(長度爲dwUs6Length-4+1)

// 下面是若干個 "Us:" - OD識別添加的註釋
BYTE 	byUsSignature[0x3];		// "Us:"
DWORD 	dwUsLength;			// Us長度
DWORD 	dwUsOffset;			// 註釋的偏移(需要加上基地址)
BYTE* 	pbyUsBuffer;			// Us內容(長度爲dwUsLength-4+1)

// 下面 Usv, 註釋, 但是貌似中間是序號,無法定位,暫不用

// 下面 UsB, 指令, 但是貌似中間是序號,無法定位,暫不用

// 下面是若干個 "Us9" - OD識別添加的參數信息,特殊標記,謹慎使用
BYTE 	byUs9Signature[0x3];	// "Us9"
DWORD 	dwUs9Length;			// Us9長度
DWORD 	dwUs9Offset;			// 參數信息的偏移(需要加上基地址)
BYTE* 	pbyUs9Buffer;			// Us9內容(長度爲dwUs9Length-4+1)

// 下面是若干個 "Us>" - OD識別添加跳轉信息,沒有跳轉也有標記,謹慎使用
BYTE 	byUsJSignature[0x3];	// "Us>"
DWORD 	dwUsJLength;			// UsJ長度
DWORD 	dwUsJOffset;			// 跳轉地址的偏移(需要加上基地址)
BYTE* 	pbyUsJBuffer;			// UsJ內容(長度爲dwUsJLength-4+1)

// 下面 Us?, 作用未知,暫不用

// 下面是若干個 "Prc" - OD識別添加CALL信息
BYTE 	byPrcSignature[0x3];	// "Prc"
DWORD 	dwPrcLength;			// Prc長度
DWORD 	dwPrcOffset;			// CALL地址的偏移(需要加上基地址)
BYTE* 	pbyPrcBuffer;			// Prc內容(長度爲dwPrcLength-4+1)

// 下面是若干個 "Swi" - OD識別添加Switch信息
BYTE 	bySwiSignature[0x3];	// "Swi"
DWORD 	dwSwiLength;			// Swi長度
DWORD 	dwSwiOffset;			// Switch地址的偏移(需要加上基地址)
BYTE* 	pbySwiBuffer;			// Swi內容(長度爲dwSwiLength-4+1)

// 下面是若干個 "Cfm" - OD識別添加,有名稱的函數調用
BYTE 	byCfmSignature[0x3];	// "Cfm"
DWORD 	dwCfmLength;			// Cfm長度
DWORD 	dwCfmOffset;			// 地址的偏移(需要加上基地址)
BYTE* 	pbyCfmBuffer;			// Cfm內容(長度爲dwCfmLength-4+1)
// Cfm的內容前四個字節是RVA,後邊是Module的名稱


// 下面是若干個 "Cfa" - OD識別添加,寄存器函數調用
BYTE 	byCfaSignature[0x3];	// "Cfa"
DWORD 	dwCfaLength;			// Cfa長度
DWORD 	dwCfaOffset;			// 地址的偏移(需要加上基地址)
BYTE* 	pbyCfaBuffer;			// Cfa內容(長度爲dwCfaLength-4+1)

// 下面是若干個 "Cfi" - CALL 立即數
BYTE 	byCfiSignature[0x3];	// "Cfi"
DWORD 	dwCfiLength;			// Cfi長度
DWORD 	dwCfiOffset;			// 地址的偏移(需要加上基地址)
BYTE* 	pbyCfiBuffer;			// Cfi內容(長度爲dwCfiLength-4+1)
// Cfi的內容一般函數的RVA




// 下面是若干個 "Bpc" - 斷點
BYTE 	byBpcSignature[0x3];	// "Bpc"
DWORD 	dwBpcLength;			// Bpc長度
DWORD 	dwBpcOffset;			// 地址的偏移(需要加上基地址)
BYTE* 	pbyBpcBuffer;			// Bpc內容(長度爲dwBpcLength-4+1)
// Bpc的buffer中有 斷點類型 + 斷點的原字節碼

// 下面是若干個 "Jdt" - 大結構,作用未知
BYTE 	byJdtSignature[0x3];	// "Jdt"
DWORD 	dwJdtLength;			// Jdt長度
BYTE* 	pbyJdtBuffer;			// Jdt內容(長度爲dwJdtLength+1)

// 下面是若干個 "Anc" - 大結構,作用未知
BYTE 	byAncSignature[0x3];	// "Anc"
DWORD 	dwAncLength;			// Anc長度
BYTE* 	pbyAncBuffer;			// Anc內容(長度爲dwAncLength+1)

// 下面是若干個 "Sva" - 作用未知
BYTE 	bySvaSignature[0x3];	// "Sva"
DWORD 	dwSvaLength;			// Sva長度
BYTE* 	pbySvaBuffer;			// Sva內容(長度爲dwSvaLength+1)

// 下面是若干個 "Pat" - 作用未知
BYTE 	byPatSignature[0x3];	// "Pat"
DWORD 	dwPatLength;			// Pat長度
BYTE* 	pbyPatBuffer;			// Pat內容(長度爲dwPatLength+1)

DWORD 	dwEndSignature;		// 0x646E450A
DWORD 	dwZero;				// 0x0

 

------------------  華麗的分割線  -------------------------------------

// 下面是我在分析的時候找到的資料,忘了出處了,非常抱歉哈

 

.UDD (User-Defined Data) file consists of unaligned variable-length records. 
Each record has the following format:
 
#define MI_SIGNATURE 0x00646F4DL // Module info signature
 #define MI_FILENAME 0x6C69460AL // Record with full path of executable
 #define MI_FILESIZE 0x7A69530AL // Record with file size
 #define MI_TIMESTAMP 0x7473540AL // Record with timestamp file data
 #define MI_USER 0x0073550AL // User data record (ORed with NM_xxx)
 #define MI_INT3BREAK 0x7470420AL // Record with breakpoint data
 #define MI_INT3BRKC 0x6370420AL // Record with checked breakpoint data
 #define MI_ANALYSIS 0x616E410AL // Record with analysis data
 #define MI_ANALPACK 0x636E410AL // Record with compressed analysis data
 #define MI_CODECRC 0x7263430AL // Record with CRC of code for analysis
 #define MI_SAVEAREA 0x6176530AL // Record with general-purpose save area
 #define MI_END 0x646E450AL // End of module info data
 
struct t_record {
 long tag; // Unique tag (MI_xxx) identifying record type
 long size; // Size of data, bytes (may be 0)
 char data[size]; // Data itself
 };
 
(Try to read tags as ASCII text). File must begin with MI_SIGNATURE record
 containing 22-byte string "Module info file v1.1\0". All other records are
 optional. If OllyDbg doesn't know the meaning of the record, it simply ignores
 it. This assures backward compatibility: breakpoints set by v1.02, for example,
 will appear in OllyDbg v1.00.
 

MI_FILENAME contains full path to the file.
 

MI_FILESIZE contains 32-bit file size. (I haven't heard yet about .exe or .dll
 that is longer than 4G bytes).
 

MI_TIMESTAMP is formed as follows:
 
FILETIME tlastwrite;
 // Get timestamp (time of last update) and size of executable file.
 hf=CreateFile(pmod->path,0,FILE_SHARE_READ|FILE_SHARE_WRITE,
 NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
 if (hf==INVALID_HANDLE_VALUE)
 return; // Unable to query executable file
 GetFileTime(hf,NULL,NULL,&tlastwrite);
 filesize=GetFileSize(hf,NULL); // Here you has file size for MI_FILESIZE
 CloseHandle(hf);
 Saverecord(f,MI_TIMESTAMP,sizeof(tlastwrite),&tlastwrite);
 

For you, the most important record is MI_USER. I use it to save all types of
 user data that are text. Size of data in MI_USER+xx records never exceeds 260
 bytes (including terminal '\0'). I don't use MI_USER directly; instead, it is
 ORed with type of user data (NM_XXX) shifted 24 bits to the left (so NM_XXX
 comes into the most significant byte of the tag).
 
#define NM_LABEL 0x31 // User-defined label
 #define NM_EXPORT 0x32 // Exported (global) name
 #define NM_IMPORT 0x33 // Imported name
 #define NM_LIBRARY 0x34 // Name from library or object file
 #define NM_CONST 0x35 // User-defined constant
 #define NM_COMMENT 0x36 // User-defined comment
 #define NM_LIBCOMM 0x37 // Comment from library or object file
 #define NM_BREAK 0x38 // Condition related with breakpoint
 #define NM_ARG 0x39 // Arguments decoded by analyser
 #define NM_ANALYSE 0x3A // Comment added by analyser
 #define NM_BREAKEXPR 0x3B // Expression related with breakpoint
 #define NM_BREAKEXPL 0x3C // Explanation related with breakpoint
 #define NM_INSPECT 0x40 // Several last inspect expressions
 #define NM_WATCH 0x41 // Watch expressions
 #define NM_ASM 0x42 // Several last assembled strings
 #define NM_FINDASM 0x43 // Several last find assembler strings
 #define NM_LASTWATCH 0x48 // Several last watch expressions
 #define NM_SOURCE 0x49 // Several last source search strings
 
#define NMHISTORY 0x40 // Converts NM_xxx to type of init list
 
struct t_midata {
 long offset; // Offset of symbol from the beginning of the module
 char sztext[size-4]; // Zero-terminated symbolic name, 256 bytes max
 };
 
Following user data types are associated with some module and can appear in any 
.udd file:
 
NM_LABEL, // User-defined label
 NM_LIBRARY, // Name extracted by object scanner
 NM_COMMENT, // User-defined comment
 NM_LIBCOMM, // Comment generated by object scanner
 NM_BREAK, // Condition related with breakpoint
 NM_BREAKEXPR, // Expression related with breakpoint
 NM_BREAKEXPL, // Explanation related with breakpoint
 NM_ANALYSE, // Comment added by analyser
 NM_ARG // Decoding of known function
 
.udd file of main module (.exe) also keeps watch expressions and history lists
 (they appear if you open pull-down window of the combobox). For this data,
 offset field is simply a 1-based ordinal:
 
NM_LABEL | NMHISTORY, // List of last entered labels
 NM_COMMENT | NMHISTORY, // List of last entered comments
 NM_BREAK | NMHISTORY, // List of last entered break conditions
 NM_BREAKEXPR | NMHISTORY, // List of last break expressions
 NM_BREAKEXPL | NMHISTORY, // List of last break explanations
 NM_INSPECT, // Inspect expressions
 NM_WATCH, // Watch expressions
 NM_ASM, // Several last assembled strings
 NM_FINDASM, // Several last find assembler strings
 NM_LASTWATCH, // Several last watch expressions
 NM_SOURCE // Several last source search strings
 

When OllyDbg encounters MI_END, it stops file processing.


------------------------------------------------------------------------------------------------------------------------------------
V1.0 from od plugin.h

// Record tags in .udd files.
#define MI_SIGNATURE   0x00646F4DL     // Module info signature
#define MI_VERSION     0x7265560AL     // OllyDbg version
#define MI_FILENAME    0x6C69460AL     // Record with full name of executable
#define MI_FILESIZE    0x7A69530AL     // Record with file size
#define MI_TIMESTAMP   0x7473540AL     // Record with timestamp file data
#define MI_SFXENTRY    0x6566530AL     // Real entry of SFX-able module
#define MI_PATCH       0x7461500AL     // Record with patch data
#define MI_USER        0x0073550AL     // Record with user-defined label/comment
#define MI_PROCDATA    0x6372500AL     // Record with procedure data
#define MI_SWDATA      0x6977530AL     // Record with switch data
#define MI_CALLFINT    0x6966430AL     // Record with internal call		(前四個字節Caller,後四個字節Call)
#define MI_CALLFMOD    0x6D66430AL     // Record with intermodular call
#define MI_CALLFABS    0x6166430AL     // Record with absolute call
#define MI_INT3BREAK   0x7470420AL     // Record with breakpoint data
#define MI_INT3BRKC    0x6370420AL     // Record with checked breakpoint data
#define MI_HDWRBREAK   0x7262480AL     // Record with hardware breakpoint data
#define MI_JDDATA      0x74644A0AL     // Record with all module jump data
#define MI_ANALYSIS    0x616E410AL     // Record with analysis data
#define MI_ANALPACK    0x636E410AL     // Record with compressed analysis data
#define MI_AHINT       0x7468410AL     // Record with analysis hint data
#define MI_TRACE       0x6172540AL     // Record with trace data
#define MI_TRACEPACK   0x6372540AL     // Record with compressed trace data
#define MI_CODECRC     0x7263430AL     // Record with CRC of code for analysis
#define MI_SAVEAREA    0x6176530AL     // Record with general-purpose save area
#define MI_END         0x646E450AL     // End of module info data
// Tags reserved for 3rd-party plugins.
#define MI_WINJUG      0x67754A0AL     // WindowJuggler by EsseEmme
#define MI_WINJU1      0x31754A0AL
#define MI_WINJU2      0x32754A0AL
#define MI_WINJU3      0x33754A0AL
#define MI_APPST       0x73614F0AL     // OllyAppStarter by Homunculus


// Types of names used in name functions. Note that higher-priority types have
// smaller identifiers!
#define NM_NONAME      0x00            // Undefined name
#define NM_ANYNAME     0xFF            // Name of any type
// Names saved in the data file of module they appear.
#define NM_PLUGCMD     0x30            // Plugin commands to execute at break
#define NM_LABEL       0x31            // User-defined label
#define NM_EXPORT      0x32            // Exported (global) name
#define NM_IMPORT      0x33            // Imported name
#define NM_LIBRARY     0x34            // Name from library or object file
#define NM_CONST       0x35            // User-defined constant
#define NM_COMMENT     0x36            // User-defined comment
#define NM_LIBCOMM     0x37            // Comment from library or object file
#define NM_BREAK       0x38            // Condition related with breakpoint
#define NM_ARG         0x39            // Arguments decoded by analyzer
#define NM_ANALYSE     0x3A            // Comment added by analyzer
#define NM_BREAKEXPR   0x3B            // Expression related with breakpoint
#define NM_BREAKEXPL   0x3C            // Explanation related with breakpoint
#define NM_ASSUME      0x3D            // Assume function with known arguments
#define NM_STRUCT      0x3E            // Code structure decoded by analyzer
#define NM_CASE        0x3F            // Case description decoded by analyzer
// Names saved in the data file of main module.
#define NM_INSPECT     0x40            // Several last inspect expressions
#define NM_WATCH       0x41            // Watch expressions
#define NM_ASM         0x42            // Several last assembled strings
#define NM_FINDASM     0x43            // Several last find assembler strings
#define NM_LASTWATCH   0x48            // Several last watch expressions
#define NM_SOURCE      0x49            // Several last source search strings
#define NM_REFTXT      0x4A            // Several last ref text search strings
#define NM_GOTO        0x4B            // Several last expressions to follow
#define NM_GOTODUMP    0x4C            // Several expressions to follow in Dump
#define NM_TRPAUSE     0x4D            // Several expressions to pause trace
// Pseudonames.
#define NM_IMCALL      0xFE            // Intermodular call

#define NMHISTORY      0x40            // Converts NM_xxx to type of init list

 

 

結束!

 

如果有什麼問題,歡迎留言討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章