How to find malware (no) with WinDbg

How to find malware (no) with WinDbg


Introduction


In this article I will show how, for example, using WinDbg to find which malware (or not) replaced the address of a system function call in a DLL loaded by some application. So, for example, I was looking for why the protection module does not load into the 1C configuration .
To demonstrate, we need an application that loads a couple of DLLs: one of them is called victim ( victim ), the other -predator injector . The latter is introduced into the victim, replacing the call to the system function (for simplicity, take Sleep ), and will call AV under certain conditions (which will be needed in the next article).


Because applications written in Delphi do not β€œfall” into core-dump due to unhandled exceptions, then our main application (DLLInjectionDemo) is written in C, linked by early binding to the victim DLL, and for ease of reproducing the situation, it will load the DLL-injector passed in options at startup, and invoke a method in it that will harm the victim. Specifically for this article, an application written in any programming language would be suitable for us, but we will kill two birds with one stone.


Application source codes are written in C and Delphi 10.3 Rio Community Edition, and MinGW and Delphi are compiled, as for Win32, and for Win64 (as well as FPC in Lazarus).


So we compile both DLLs and the main application


> msbuild /t:build victim.dproj /p:Platform=Win32;Config=Debug;DCC_Exeoutput=.
> msbuild /t:build injector.dproj /p:Platform=Win32;Config=Debug;DCC_Exeoutput=.
> mingw32-make

To build with MinGW make, you need to register it in PATH, of course


:


C:\Users\demo>DLLInjectionDemo.exe
Sleeping 100 milliseconds
Done!

-L injector (, , , - )


c:\Users\demo>DLLInjectionDemo.exe -L injector
Loading injector
Searching...
oleaut32.dll
advapi32.dll
user32.dll
kernel32.dll
kernel32.dll
user32.dll
version.dll
kernel32.dll
kernel32.dll
netapi32.dll
oleaut32.dll
Injected
Sleeping 100 milliseconds
New sleep instead of 100
Done!

, , Sleep - . ( , ). ( , GUI-, , , , -i(interactive)).


c:\Users\demo>DLLInjectionDemo.exe -i -L injector
Loading injector
Searching...
oleaut32.dll
advapi32.dll
user32.dll
kernel32.dll
kernel32.dll
user32.dll
version.dll
kernel32.dll
kernel32.dll
netapi32.dll
oleaut32.dll
Injected
Sleeping 100 milliseconds
New sleep instead of 100
Done!
Press ENTER...

( ). : , , , , " ...", .


WinDbg, :


File β€” Open Crash Dump (Ctrl+D)


:


%PROGRAM FILES%\Windows Kits\10\Debuggers\x64\windbg.exe" -z C:\Users\demo\App Data\Local\Temp\DLLInjectionDemo.DMP


Loading Dump File [C:\Users\alex\AppData\Local\Temp\DLLInjectionDemo.DMP]
User Mini Dump File with Full Memory: Only application data is available

Symbol search path is: srv*
Executable search path is: 
Windows 7 Version 7601 (Service Pack 1) MP (4 procs) Free x64
Product: WinNt, suite: SingleUserTS
Machine Name:
Debug session time: Thu Jul  4 08:46:18.000 2019 (UTC + 3:00)
System Uptime: 17 days 12:25:45.404
Process Uptime: 0 days 0:00:10.000
........................
For analysis of this file, run !analyze -v
ntdll!NtRequestWaitReplyPort+0xa:
00000000`77bcddfa c3              ret

For analysis of this file, run !analyze -v ( , ).


IAT β€” (Import Address Table) β€” DLL, (? , IAT ;) ). , PE- ( DLL ) WinDbg Windows 10 SDK ( Windows 7) , " ", WinDbg 6, .


. :


lm


0:000> lm
start             end                 module name
00000000`003b0000 00000000`003db000   injector   (deferred)             
00000000`00400000 00000000`00412000   DLLInjectionDemo   (deferred)             
00000000`00520000 00000000`00616000   victim     (deferred)             
00000000`6e580000 00000000`6e5b4000   libmingwex_2   (deferred)             
00000000`72870000 00000000`72886000   netapi32   (deferred)             
...

Nota bene: 32- , 64-...


, DLL , IAT , !dh -a:


!dh 009c0000 -a



!dh victim -a
0:000> !dh victim -a

File Type: DLL
FILE HEADER VALUES
     14C machine (i386)
       A number of sections
5E5F4251 time date stamp Wed Mar  4 09:53:21 2020

       0 file pointer to symbol table
       0 number of symbols
      E0 size of optional header
    A18E characteristics
            Executable
            Line numbers stripped
            Symbols stripped
            Bytes reversed
            32 bit word machine
            DLL

OPTIONAL HEADER VALUES
     10B magic #
    2.25 linker version
   CE400 size of code
   1BA00 size of initialized data
       0 size of uninitialized data
   CF79C address of entry point
    1000 base of code
         ----- new -----
0000000000400000 image base
    1000 section alignment
     200 file alignment
       2 subsystem (Windows GUI)
    5.00 operating system version
    0.00 image version
    5.00 subsystem version
   F6000 size of image
     400 size of headers
       0 checksum
0000000000000000 size of stack reserve
0000000000000000 size of stack commit
0000000000100000 size of heap reserve
0000000000001000 size of heap commit
       0  DLL characteristics
   DD000 [      A4] address [size] of Export Directory
   DA000 [    105C] address [size] of Import Directory
   F3000 [    2A00] address [size] of Resource Directory
       0 [       0] address [size] of Exception Directory
       0 [       0] address [size] of Security Directory
...

kernel32.dll ( Sleep)


Nota bene: 32- _IMAGE_IMPORT_DESCRIPTOR 64-. , , Delphi .


...
  _IMAGE_IMPORT_DESCRIPTOR 00000000005fa03c
    kernel32.dll
              005FA398 Import Address Table
              005FA11C Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

       003C7C7C    0 Sleep
       76EE184A    0 VirtualFree
       76EE1832    0 VirtualAlloc
       76EE16DC    0 lstrlenW
       76EE4422    0 VirtualQuery
       76EE110C    0 GetTickCount
...

,


`kernel32.dll`
0:000> !dh kernel32

File Type: DLL
FILE HEADER VALUES
     14C machine (i386)
       4 number of sections
5708A7E3 time date stamp Sat Apr  9 10:57:39 2016

...
         ----- new -----
0000000076ed0000 image base
...

.. 0000000076ed0000


, β€” ?


WinDbg lm :


0:000> lma 003C7C7C    
Browse full module list
start             end                 module name
00000000`003b0000 00000000`003db000   injector   (deferred)             

, ! . ( v lm)


0:000> lma 003C7C7C v
Browse full module list
start             end                 module name
00000000`003b0000 00000000`003db000   injector   (deferred)             
    Image path: z:\habr\DLLInjectionDemo\injector.dll
    Image name: injector.dll
    Browse all global symbols  functions  data
    Timestamp:        Wed Mar  4 09:53:12 2020 (5E5F4248)
    CheckSum:         00000000
    ImageSize:        0002B000
    Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4
    Information from resource tables:

!


Image path: C:\Users\demo\injector.dll


, .


So in real conditions, I quickly managed to find some strange DLL on the preinstalled OS from the manufacturer that intercepted the function call WriteFile.


I use the application from this article in the next one, in which I want to show the reader how to use WinDbg to find out why (or at least somewhere) the application crashed with Access Violation, which occurred in a DLL written in Delphi when remote debugging is not available for some reason. either reason. Despite the fact that Delphi does not have tools for analyzing the application dump, it does not know how to generate PDB files.


All Articles