OllyDbg über den Tod - Speichern der Funktionsweise der Debug-Sitzung

Wenn Sie OllyDbg nicht zum Debuggen Ihrer eigenen Anwendungen verwenden, für die Sie Debugging-Informationen haben, sondern für Reverse Engineering oder Recherchen von Drittanbietern, besteht Ihre typische Aktivität darin, den Maschinencode eines anderen Produkts zu untersuchen, die Essenz der Ereignisse zu verstehen und eine große Anzahl von Etiketten (Etiketten) zu platzieren ) und Kommentare im gesamten Code sowie Datenabschnitte. Sie untersuchen systematisch die Essenz von Prozeduren / Funktionen und Variablen und geben ihnen Namen, die Ihr Verständnis ihres Zwecks widerspiegeln.

OllyDbg benötigt keine Einführung für alle, die mit Debugging, Reverse Engineering-Anwendungen, Erforschung oder Umgehung von Sicherheitsmechanismen usw. befasst sind.  Dies ist einer der besten Debugger im Benutzermodus für Windows, obwohl es viele Mängel und Mängel gibt, die nicht vertuscht werden können.

Und jetzt, nach ein paar Stunden (oder sogar Tagen) Arbeit, als Sie Hunderte oder sogar Tausende von Prozeduren und Variablen herausgefunden und unterschrieben haben, OllyDbgplötzlich friert ein oder stürzt ab und nimmt Ihre gesamte Arbeit weg (was nicht nur Beschriftungen und Kommentare in großer Anzahl, sondern auch Haltepunkte und Änderungen an den richtigen Stellen enthalten kann). Dies ist Zeitverschwendung und ein ungeheuer demotivierender Faktor, von dem man aufgibt und blass wird.







In diesem Artikel geht es darum, wie ich OllyDbg in einem solchen Notfall verwendet habe, um OllyDbg (teilweise) schnell zurückzuentwickeln, die an einem Thread hängenden Daten zu speichern und ein Rezept für Maßnahmen im Falle solcher Katastrophen zu entwickeln.







Da Sie den Artikel weiter gelesen haben, sollten wir uns von Anfang an auf einige Dinge einigen:







  1. OllyDbg 1.xx, OllyDbg 2.xx, , - , 1.xx ( ).
  2. OllyDbg , , , .. « » —  « », , , , OllyDbg. , , — .
  3. IDA Pro , OllyDbg . Audi « BMW» . — , .
  4. , . « » . howto- , SSH, , , , ? , « BSOD» — , , . ?


«» , , , , , . :







  • (Labels) — OllyDbg , , .
  • (Comments) — .
  • (Breakpoints) — .
  • (Hints) — OllyDbg, , 4 4 , DWORD.


, , , . , , . , , , — - .







, , , , { → } OllyDbg names. .







names PDK
  • NM_LABEL — User-defined label
  • NM_EXPORT — Exported (global) name
  • NM_IMPORT — Imported name
  • NM_LIBRARY — Name extracted from library, object file or debug data
  • NM_CONST — User-defined constant (currently not implemented)
  • NM_COMMENT — User-defined comment
  • NM_LIBCOMM — Automatically generated comment from library or object file
  • NM_BREAK — Condition related with breakpoint
  • NM_ARG — Arguments decoded by analyser
  • NM_ANALYSE — Comment added by analyser
  • NM_BREAKEXPR — Expression related with breakpoint
  • NM_BREAKEXPL — Explanation related with breakpoint
  • 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 :







  1. — . BSOD . .
  2. — . , , , , « » « ». ( ?), . . , OllyDbg, , - , .
  3. . OllyDbg . , OllyDbg.exe, . : , OllyDbg «» 27 . , . , OllyDbg, deadlock - Windows, - ( - ). , Microsoft- Spy++, « » , Spy++ GUI- DLL, . - , GUI-. , , . .
  4. OllyDbg UDD-, . UDD- , OllyDbg . , . OllyDbg , , — , , UDD-, . , - . , OllyDbg UDD, UDD-. , UDD- , , , , .  — DLL. OllyDbg «» UDD-, , UDD-, , UDD-. UDD-.




, , , , , , , (..  — ).







UDD — . , , . , . .







UDD :







  1. . , git ( ) ( , ). diff , (, custom diff git). , merge — .
  2. , , . , UDD .


- , . - , , . - ( — , , , , , , ..) - - .







- VCS Git , . : ( WinMain()



), — ( , ). , , . , ( memcpy



, strncat



, qsort



). , , (merge conflict), , . « », .







, - - , , , « », , « », . , , - , , ( , new



).







, - ( ) , , , , .







« »

, , , DAW . : - 5—6 , , , , , . merge, , , — VST- , — - . , , , , git diff



, VST- VST- -.







UDD- - , , OllyDbg, ( ( , ) ) ( ), .

Markup Dumper Plugin

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 , ( ), - , :

image

, , , , (git add --patch



).







, ( ) , , , - .







, , DVCS , №1 (BSOD ) №4 ( UDD).







№2 №3 ( ). .









, « », « », «»,  — SEH-, , , « » ( SEH- EXCEPTION_NONCONTINUABLE



).







OllyDbg ( ) — EXCEPTION_ACCESS_VIOLATION



(0xc0000005



), . , EIP , ESP/EBP , . , ( ) . , - . « » , (GetMessageTranslateMessageDispatchMessage), , . 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.







, OllyDbg

, 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 — - . , .







«» :

Exotischer Käfer







, 0xC000026E



( 0xC000005



STATUS_ACCESS_VIOLATION



, / ), 0x004436E8



. , , 0x00400000



EXE-, - ( ).







«», , ( , ), . , 0xC000026E



. , STATUS_VOLUME_DISMOUNTED



. OllyDbg - 0x004436E8



, , , OllyDbg?







, , :







  • OllyDbg.exe . , . , OllyDbg.exe, , «Go to address» — , :

    Zum Ausdrucksdialog gehen
  • - 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) , , , .







Bild alt ( ), 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?







  • {, , }. , — . : ( O(n) ), , , , , , , , .
  • , (). , O(lb(n)) — , 30 . ( , ). , «» , .
  • , (RB, AVL, ..). , , ( ) , / , / .


, , «», . — , .







, OllyDbg OllyDbg _Insertname()



, :

iInsertname unter dem Disassembler

, , 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()



, :

Anordnung von Tags und Kommentaren







!







, , . 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 , : , - .







, ?

Fortsetzung des Codes Insertname ()

, : - , , , , VirtualAlloc



VirtualFree



memcpy



, , , strlen



memcpy



.







, name' , , , , , , —  , .







, :

Wir kehren die Funktion Insertname () weiter um







!







, . , :







    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) . , / .







OllyDbg

, , , 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



, , . . , , , — , - , . , , , , .







, 255 ?

-, , Insertname()



. , watch expressions, , , — name-. , 255 , .







-, OllyDbg , TEXTLEN



, . , Insertname()



Quickinsertname()



, . . , , OllyScript, . , , , .







.

OllyDbg (, ).







CNFFMappedStream::Unmap



, ?Unmap@CNFFMappedStream@@UAGXEPAPAX@Z



, OllyDbg « ». . , , . :







virtual void __stdcall CNFFMappedStream::Unmap(unsigned char,void * *)
      
      





. . , , COMDAT folding.







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()



, , , , ( ):

Globale Variablen, die Datenblöcke beschreiben

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



, — .

Zwei Datenblöcke

, . , , , — , 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.







Dumping von 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



, , .







?



, . . ?







, :







  1. , Markup Dumper, , , ( , ). , OllyDbg. , 5 , . ( ) .
  2. «» , ( , ) OllyDbg, API-, . .. Insertname()



    ( ). , UDD-.
  3. , , — 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 . , , , , , - .








All Articles