あなたは使用している場合はOllyDbgを(ラベルではなく、あなたがデバッグ情報ているため、独自のアプリケーションをデバッグするために、しかし、リバースエンジニアリングまたはサードパーティの研究のために、あなたの典型的な活動は、他の誰かの製品のマシンコードに踏み込んで起こっている物事の本質を理解し、大量のラベルを配置しています)およびコード全体のコメント、およびデータセクション。プロシージャ/関数および変数の本質を体系的に調査し、それらの目的の理解を反映する名前を付けます。
そして今、数時間(または数日)の作業の後、数百、さらには数千の手順と変数を見つけて署名したとき、OllyDbg突然フリーズまたはクラッシュし、すべての作業が失われます(ラベルやコメントが多数含まれるだけでなく、ブレークポイントや変更が適切な場所に配置される場合もあります)。これは時間の無駄であり、途方もなく意欲をそそる要因であり、そこからあきらめて青ざめます。
この記事では、このような緊急時にOllyDbgを使用して、OllyDbgを(部分的に)すばやくリバースエンジニアリングし、スレッドにぶら下がっているデータを保存し、このような災害が発生した場合のアクションのレシピを作成する方法について説明します。
あなたは記事を読み続けているので、最初からいくつかのことに同意しましょう:
- OllyDbg 1.xx, OllyDbg 2.xx, , - , 1.xx ( ).
- OllyDbg , , , .. « » — « », , , , OllyDbg. , , — .
- IDA Pro , OllyDbg . Audi « BMW» . — , .
- , . « » . howto- , SSH, , , , ? , « BSOD» — , , . ?
«» , , , , , . :
- (Labels) — OllyDbg , , .
- (Comments) — .
- (Breakpoints) — .
- (Hints) — OllyDbg, , 4 4 , DWORD.
, , , . , , . , , , — - .
, , , , { → } OllyDbg names. .
- NM_LABEL-ユーザー定義のラベル
- NM_EXPORT-エクスポートされた(グローバル)名前
- NM_IMPORT-インポートされた名前
- NM_LIBRARY-ライブラリ、オブジェクトファイル、またはデバッグデータから抽出された名前
- NM_CONST-ユーザー定義の定数(現在は実装されていません)
- NM_COMMENT-ユーザー定義のコメント
- NM_LIBCOMM-ライブラリまたはオブジェクトファイルから自動的に生成されたコメント
- NM_BREAK-ブレークポイントに関連する条件
- NM_ARG-アナライザーによってデコードされた引数
- NM_ANALYSE-アナライザーによって追加されたコメント
- NM_BREAKEXPR-ブレークポイントに関連する式
- NM_BREAKEXPL-ブレークポイントに関連する説明
- NM_ASSUME — Assume function with known arguments
- NM_STRUCT — Code structure decoded by analyzer
- NM_CASE — Case description decoded by analyzer
- NM_PLUGCMD — Plugin commands to execute at breakpoint
- NM_INSPECT — Several last entered inspect expressions
- NM_WATCH — Watch expressions
( .udd), — . , - , , , ( ) . , , UDD-, supercool.dll, foo.exe, bar.exe, supercool.dll.
, , OllyDbg ( ). OllyDbg , .
, UDD-? -, , UDD- , . UDD . «Save everything to UDD». «Update .udd file now» — (EXE/DLL/OCX) . , Modules , - . , UDD, . 20 - , UDD , . -, .
4 :
- — . BSOD . .
- — . , , , , « » « ». ( ?), . . , OllyDbg, , - , .
- . OllyDbg . , OllyDbg.exe, . : , OllyDbg «» 27 . , . , OllyDbg, deadlock - Windows, - ( - ). , Microsoft- Spy++, « » , Spy++ GUI- DLL, . - , GUI-. , , . .
- OllyDbg UDD-, . UDD- , OllyDbg . , . OllyDbg , , — , , UDD-, . , - . , OllyDbg UDD, UDD-. , UDD- , , , , . — DLL. OllyDbg «» UDD-, , UDD-, , UDD-. UDD-.
, , , , , , , (.. — ).
UDD — . , , . , . .
UDD :
- . , git ( ) ( , ). diff , (, custom diff git). , merge — .
- , , . , UDD .
- , . - , , . - ( — , , , , , , ..) - - .
- VCS Git , . : ( WinMain()
), — ( , ). , , . , ( memcpy
, strncat
, qsort
). , , (merge conflict), , . « », .
, - - , , , « », , « », . , , - , , ( , new
).
, - ( ) , , , , .
UDD- - , , OllyDbg, ( ( , ) ) ( ), .
Markup Dumper, markup — , . «», — markup, , , .
OllyDbg, , , . , - . , , - .
@ MODULE OLLYDBG @ VERSION 1.0.10.0 @ BASEADDR 00400000 @ CHECKSUM 17ca77a5 // // Section: .text // LABEL 0040c214 like_ParseStuff CMT 0040c4c5 colon case CMT 0040c521 eq case CMT 0040c575 checking for 1-byte typespec CMT 0040c578 jump if more than 2 byte spec CMT 00463f08 checking arg1 (addr) against 0 CMT 00463f0c EDI = arg2 (type of name) CMT 00463f0f goto error if addr==NULL CMT 00463f11 checking [addr] against 0 CMT 00463f15 goto error if 0 ... LABEL 004642fb Insertname_EPILOGUE LABEL 004a3530 like_memcpy LABEL 004a36d4 like_strlen LABEL 004a38bc parse_keyword_1 LABEL 004a6c2c like_sprintf // // Section: .data // LABEL 004eae14 pNamesBlock LABEL 004eae18 cNameEntriesCur LABEL 004eae1c cNameEntriesMax LABEL 004eae30 pNamesStringPool LABEL 004eae34 cbStringPoolUsed LABEL 004eae38 cbStringPoolTotal LABEL 004eae3c xxxWtfNameStringPoolrelated
. , .
, CMT
, LABEL
— . . , git diff , , — , . LABEL
, CMT
, , , git diff , ( ), - , :
, , , , (git add --patch
).
, ( ) , , , - .
, , DVCS , №1 (BSOD ) №4 ( UDD).
№2 №3 ( ). .
, « », « », «», — SEH-, , , « » ( SEH- EXCEPTION_NONCONTINUABLE
).
OllyDbg ( ) — EXCEPTION_ACCESS_VIOLATION
(0xc0000005
), . , EIP , ESP/EBP , . , ( ) . , - . « » , (GetMessage→TranslateMessage→DispatchMessage), , . OllyDbg GUI-, , , .
, - , . EBP . , ( ) , retn
(EIP) .
, , , — () . EXCEPTION_ACCESS_VIOLATION
, ( ). , , , , , DEP, . , ( DEP ), ( , ) , . , , , EIP , , ( , ). , — .
, , , , Markup Dumper, message loop ( ) .
( ), OllyDbg , ( , ), .
, , , EIP , . , OllyDbg , , ( ). , . . , : , , - .
, - , . , , , , , .
Findname()
Findnextname()
— API-, OllyDbg .
void DumpMarkupEx(FILE * fiOutput, int iNameType, char* pszNameType, ulong vaStart, ulong vaLimit)
{
ulong vaCur;
char rgchName[TEXTLEN];
Findname(vaStart-1, iNameType, NULL);
while(vaCur = Findnextname(rgchName) && vaCur<vaLimit)
if(vaCur >= vaStart) fprintf(fiOutput, "%5s %.8x %s\n", pszNameType, vaCur, rgchName);
}
void DumpMarkup(FILE * fiOutput, ulong vaStart, ulong vaLimit)
{
DumpMarkupEx(fiOutput, NM_LABEL, "LABEL", vaStart, vaLimit
DumpMarkupEx(fiOutput, NM_COMMENT, "CMT", vaStart, vaLimit)
}
: TEXTLEN , , API- Findnextname()
rgchName
. .
, OllyDbg. , — /, .
, , , OllyDbg. , , OllyDbg - (, OllyDbg) .
, - . , - . ( ), (unwinding) , message loop. , Markup Dumper, , , - — EIP , , — , , , , .
10—20% OllyDbg . 80—90% , OllyDbg - WinAPI-, , , . , , - NtWaitForSingleObject, . wait-, - , . Windows deadlock, . , .
, OllyDbg , . , ( New origin here EIP). New Origin Here, EIP — WinAPI- SetThreadContext()
. , Windows , — . APC. «» APC.
, Windows, OllyDbg, , , deadlock- , , UI , , (WaitForDebugEvent
, ReadProcessMemory
, WriteProcessMemory
) — . , watchdog-, GUI- ( ) . , Spy++ , .
, , OllyDbg , . OllyDbg — , , , . , TLS , , , , , . , , , , /, .
- OllyDbg , CreateRemoteThread()
.
push param1 push param2 push param3 call <____> int3 int3 int3
( ), , int3 — , ( ) -.
, , , OllyDbg . , . , .
, , .
, , №2 — - . , .
«» :

, 0xC000026E
( 0xC000005
— STATUS_ACCESS_VIOLATION
, / ), 0x004436E8
. , , 0x00400000
EXE-, - ( ).
«», , ( , ), . , 0xC000026E
. , STATUS_VOLUME_DISMOUNTED
. OllyDbg - 0x004436E8
, , , OllyDbg?
, , :
- OllyDbg.exe . , . , OllyDbg.exe, , «Go to address» — , :

- - Ctrl+G, (,
at
CommandBar, Ctrl+G). - , .
0x004436E8
— — , «Go to expression». - CS:EIP=
001B:004436E8
004436E8
( ),004436E8
, . , x86- , ( PE CR0 ) ( PG CR0 ). - () , — P (Present) PDE PTE .
- #PF (Page Fault), .
- Windows, (
KiTrap0E()
→MmAccessFault()
→ .) — - ( ) ( , ( user-mode)VirtualAlloc
, , - , image-backed swap-backed copy-on-write ). -
00443000
, , , image-backed. - - (
h:\soft\odbg\ollydbg.exe
), , ,H:\
, . ,STATUS_VOLUME_DISMOUNTED
(0xC000026E
).
, . , , , (working set) , , , .
( ), OllyDbg , - VirtualQueryEx()
, - . — , ( ) , , , , .
, ( DLL, OllyDbg) H:\
. Markup Dumper , . , (), , ( «» , ) .
, , .
, , , , , ( EIP - ) .
- , , OllyDbg (names), , , .
: . , - , . (Oleh Yuschuk), ...
, , , , , , .
Process Explorer , . , , - . Process Explorer ( VAD-), — , ReadProcessMemory()
. , .
— , «», «», . , , — - OllyDbg OllyDbg. H:\
.
API- Insertname()
, name ( , - ) names. names — , (markup), .
, names?
- {, , }. , — . : ( ), , , , , , , , .
- , (). , — , 30 . ( , ). , «» , .
- , (RB, AVL, ..). , , ( ) , / , / .
, , «», . — , .
, OllyDbg OllyDbg _Insertname()
, :
, , EBX, ESI, EDI, — . , — VirtualAlloc()
VirtualFree()
, memcpy
, - OllyDbg .
- : Process Monitor ( FileMon), , - ( TEST.DLL
), - TEST.UDD
, TEST.ARG
( , ). ARG- , , , OllyDbg
- ARG-.
- OllyDbg , ARG-, . : ARG- OllyDbg. ARG- custom-, , , OllyDbg — , , , VirtualAlloc()
VirtualFree()
, , , (push 4
fProtect = 4
, fProtet = PAGE_READWRITE
).
: ARG-, . . , ARG-.
like_memcpy
( memcpy()
libc) ,
Arg3 = ... Arg2 = ... Arg1 = ...
count = ... src = ... dest = ...
, , clr = 8000FF
clr = (R=255 G=0 B=128)
ARG- , OllyDbg «Custom function descriptions», .
, RTFM twice.
, - — … , .
, ? - , . () — , .
:
- ( ),
malloc()
/HeapAlloc()
,VirtualAlloc()
, (, 4 ) . , EDX*24, EDX , - . , 24 — . - Plugin Development Kit (PDK) , Insertname() Quickinsertname() Mergequicknames(), names — API- . , , .
API- Insertname()
, :


, , . Names, , — , , , 24 , 12 , DWORD- ( — , , ). 24 12, 2 — , .
, Insertname()
:
int Insertname(ulong addr,int type,char *name)
{
//
//
//
if(addr == NULL ||
name == NULL ||
type == NM_ANYNAME || type == NM_NONAME)
{
return -1;
}
//
// , name-
//
if(!pNamesBlock) return -1;
if(!(cNameEntriesCur < cNameEntriesMax) && cNameEntriesMax < 1000000)
{
//
// ,
//
void* const pNewBlock = VirtualAlloc(NULL,
2 * cNameEntriesMax * sizeof(NAME_REC),
MEM_COMMIT,
PAGE_READWRITE);
if(pNewBlock)
{
//
// ,
// .
//
memcpy(pNewBlock, pNameBlock, cNameEntriesMax * sizeof(NAME_REC));
VirtualFree(pNamesBlock, 0, MEM_RELEASE);
//
// ,
// ,
// .
//
pNamesBlock = (NAME_REC*)pNewBlock;
cNameEntriesMax *= 2;
}
}
// 00463FB0
, , name
NULL, , -1
. API-:
Insertname
Inserts new or replaces existing name of given type in the name table. If name is NULL or empty, entry is deleted. Returns 0 on success and -1 on error. Note: do not call this function between calls to Quickinsertname and Mergequicknames!
int Insertname(ulong addr,int type,char *name);**
Parameters:
addr — name address;
type — name type ( NM_xxx for predefined types);
name — name to insert. If name is NULL or empty, entry is removed from the name table.
. , - OllyDbg.
. OllyDbg OllyDbg, OllyDbg , OllyDbg , {, , } c «» «» ( NM_LABEL
NM_COMMENT
).
:
| DWORD | Address |
| DWORD | Value |
| DWORD | NameType |
, «Value» names, , - ASCII-. , , — - .
, , - ( ), . - .
, OllyDbg , VirtualAlloc DWORD , : , - .
, ?
, : - , , , , VirtualAlloc
VirtualFree
memcpy
, , , strlen
memcpy
.
, name' , , , , , , — , .
, :


, . , :
if(!(cbStringPoolUsed + TEXTLEN < cbStringPoolTotal))
{
char* pNewStringPool;
int cbDesiredNewPoolSize;
if(GlobVarC > 4096 || cbStringPoolTotal > 320000000)
cbDesiredNewPoolSize = cbStringPoolTotal;
else
cbDesiredNewPoolSize = cbStringPoolTotal * 2;
pNewStringPool = VirtualAlloc(NULL,
cbDesiredNewPoolSize,
MEM_COMMIT,
PAGE_READWRITE);
if(pNewStringPool)
{
int cchUsed = 0;
int i;
for(int i = 0; i < cNameEntriesCur; i++)
{
char* pszCurString = pNamesStringPool + pNamesBlock[i].Offset;
int cchCurString = strlen(pszCurString) + 1;
memcpy(pNewStringPool + cchUsed, pszCurString, cchCurString);
pNamesBloc[i].Offset = cchUsed;
ccUsed += cchCurString;
}
VirtualFree(pNamesStringPool, 0, MEM_RELEASE);
pNamesStringPool = pNewStringPool;
cbStringPoolUsed = cchUsed;
cbStringPoolTotal = cbDesiredNewPoolSize;
GlobalVarC = 0;
}
}
, (, - name', ) , (), , 320 , - ( GlobVarC
) 4096.
, memcpy
? , — ( , , ). , , , - , . , , , , 320 GlobVarC
> 4096. , GlobVarC
— , (delayed) . , / .
, , , cbStringPoolUsed + TEXTLEN < cbStringPoolTotal
,
cchCurString = strlen(Value) + 1;
if(!(cbStringPoolUsed + cchCurString < cbStringPoolTotal))
-, , , , 5 , 100 , , 256 ( TEXTLEN
), .
-, 256 , - . , 255 , .
, strlen(value)
, Insertname()
, 255 !
1000 , Findname()
Findnextname()
, , .
, TEXTLEN
, , . . , , , — , - , . , , , , .
-, , Insertname()
. , watch expressions, , , — name-. , 255 , .
-, OllyDbg , TEXTLEN
, . , Insertname()
Quickinsertname()
, . . , , OllyScript, . , , , .
CNFFMappedStream::Unmap
, ?Unmap@CNFFMappedStream@@UAGXEPAPAX@Z
, OllyDbg « ». . , , . :
virtual void __stdcall CNFFMappedStream::Unmap(unsigned char,void * *)
. . , , COMDAT folding.
, . , , , , , , . , , , , , , COMDAT ( Communal Data).
« » : COMDAT, ( , , , ; , COMDAT- , , ). — COMDAT , . "ERROR"
, — , . , , --.
:
unsigned short GetCodepointLength(const char* pCodepoint)
{
#ifdef UNICODE_STRINGS
#if UNICODE_STINGS == UTF8
const char cp = *pCodepoint;
unsigned short cbExtra;
for(cbExtra = 0; (cp & 0x80) && (cbExtra < 3); cbExtra++, cp<<=1)
if(cp & 0x40) {if(!(cp & 0x20)) break; } else return 0;
return 1 + cbExtra;
#else // UCS-2 or UTF-16
return sizeof(wchar_t);
#endif
#else
return sizeof(char);
#endif
}
LONG __stdcall CFlatArrayObject::GetDimensionsCount() // for IArrayObject::GetDimensionsCount
{
return 1;
}
BOOL CAudioCodec::IsSampleFormatSupported(SAMPLE_FORMAT sf)
{
return TRUE; // We support all
}
:
mov eax, 00000001 retn 4
( Microsoft ) COMDAT-folding . .
, COMDAT folding' , , « », , //
«FOLDED:
». COMDAT-folding' ( COM COM-, E_NOTIMP
— 5—6 , , , RETN
). , . , TEXTLEN
. ? OllyScript .
API- , , , , .
, «» Insertname()
, , , , ( ):
PE- (EXE DLL) : ( ) swap-backed , image-backed, copy-on-write image-backed swap-backed, / / , PE-.
, ( , , OllyDbg , , , , .bss
) , OllyDbg ( ), , , swap-backed-.
H:\
( SSD-), OllyDbg.exe, , , ReadProcessMemory()
.
— , , , — , . , ( ) , - , , , .
, — , , , — :
-
NAME_REC
, {, , }. 12 . «» . . - , -, (, ..). «» , , . .
OllyDbg.exe
, — .
, . , , , — , 7 ( 4 ).
, . 1.10. ! 1.10, , OllyDbg, , .
, 0x004EAE14
, , , , , OllyDbg. : — API- Insertname()
. ( , ). API- . , , . , , , , VirtualFree
, , VirtualAlloc
.
, . OllyDbg , , - (ollydbg.exe
), , - . «» , , . -, , , :
struct
{
struct
{
DWORD pNamesBlock;
DWORD cNameEntriesCur;
DWORD cNameEntriesMax;
} NameBlockInfo;
struct
{
DWORD pNamesStringPool;
DWORD cbStringPoolUsed;
DWORD cbStringPoolTotal;
DWORD wtf;
} StringPool;
} Metadata;
void main()
{
HANDLE hOdbgProc;
DWORD cbRead = 0;
DWORD pid = ?????????;
hOdbgProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
ReadProcessMemory(hOdbgProc,
(LPCVOID)0x004EAE14,
&Metadata.NameBlockInfo,
sizeof(Metadata.NameBlockInfo),
&cbRead))
ReadProcessMemory(hOdbgProc,
(LPCVOID)0x004EAE30,
&Metadata.StringPool,
sizeof(Metadata.StringPool),
&cbRead))
VOID* pNamesBlock;
VOID* pNamesPool;
pNamesBlock = VirtualAlloc(0, Metadata.NameBlockInfo.cNameEntriesMax * 12, MEM_COMMIT, PAGE_READWRITE);
pNamesPool = VirtualAlloc(0, Metadata.StringPool.cbStringPoolTotal, MEM_COMMIT, PAGE_READWRITE);
ReadProcessMemory(hOdbgProc,
(LPCVOID)Metadata.NameBlockInfo.pNamesBlock,
pNamesBlock,
Metadata.NameBlockInfo.cNameEntriesMax * 12,
&cbRead))
ReadProcessMemory(hOdbgProc,
(LPCVOID)Metadata.StringPool.pNamesStringPool,
pNamesPool,
Metadata.StringPool.cbStringPoolTotal,
&cbRead))
DumpBlockToFile(&Metadata, sizeof(Metadata), "names-meta.dat");
DumpBlockToFile(pNamesBlock, Metadata.NameBlockInfo.cNameEntriesMax * 12, "names-tbl.dat");
DumpBlockToFile(pNamesPool, Metadata.StringPool.cbStringPoolTotal, "names-pool.dat");
VirtualFree(pNamesBlock, 0, MEM_RELEASE);
VirtualFree(pNamesPool, 0, MEM_RELEASE);
}
— , , ReadProcessMemory
. , - , - — , , , -, . , ( ), - — OllyDbg.

, , OllyDbg, , - , .
- , , , , . , , , . , .
- , , , . , , , - ?
-
VirtualAlloc()
, , (4K x86). - 0x00000FFF , . - ,
VirtualAlloc()
Insertname()
- , , , SYSTEM_INFO::dwAllocationGranularity, x86 64K. 16 , . -
VirtualQueryEx()
, ()VirtualAlloc()
, (PAGE_READWRITE
), , . - , «» .
- ( ) , , — . , , 32- , 640 . , , ,
NM_xxxx
, PDK. - ( ) - , . , -
, ( ), — , (.. ). , , . - , , ( ).
, - , « » — , . , API- Insertname
, , .
?
, . . ?
, :
- , Markup Dumper, , , ( , ). , OllyDbg. , 5 , . ( ) .
- «» , ( , ) OllyDbg, API-, . ..
Insertname()
( ). , UDD-. - , , — OllyDbg , / . UDD-. - , . , , , .
, , . , :
typedef struct
{
DWORD Va; // virtual address of NAME in debugger process
DWORD Offset; // offset of NAME's value in string pool
DWORD Type; // one of NM_xxxxx values
} NAME_REC;
, for
-, cNameEntriesCur
Insertname()
, , .
P.S. . , , , , . , howto-, , , - Git VCS, - API- OllyDbg, OllyDbg, Windows . , , , , , - .