Skip to main content

Deep Dive to Windows, Part 2


In this section, I’d like to disassemble our main function which we’ve written in series 1 and would like to see how it looks like. Also would like to see if we can see the string “Hello World”.
I’ve launched my sample executable using WinDbg.
Then Issued following command:

x sample_hello!*main*
*** WARNING: Unable to verify checksum for Sample_Hello.exe
00419048          Sample_Hello!__native_dllmain_reason = 0xffffffff
0041917c          Sample_Hello!mainret = 0n0
004114b0          Sample_Hello!wmain (int, wchar_t **)
004122b0          Sample_Hello!__tmainCRTStartup (void)
00412290          Sample_Hello!wmainCRTStartup (void)
00413592          Sample_Hello!__wgetmainargs ()
0041a3d8          Sample_Hello!_imp____wgetmainargs =
Since we know my intended function is ‘main’ so I searched for it. The highlighted one is our main function.

Then unassembled the function using following command:

0:000> uf Sample_Hello!wmain
Sample_Hello!wmain [f:\fordebugging\sample_hello\sample_hello\sample_hello.cpp @ 10]:
   10 004114b0 55              push    ebp
   10 004114b1 8bec            mov     ebp,esp
   10 004114b3 81eccc000000    sub     esp,0CCh
   10 004114b9 53              push    ebx
   10 004114ba 56              push    esi
   10 004114bb 57              push    edi
   10 004114bc 8dbd34ffffff    lea     edi,[ebp-0CCh]
   10 004114c2 b933000000      mov     ecx,33h
   10 004114c7 b8cccccccc      mov     eax,0CCCCCCCCh
   10 004114cc f3ab            rep stos dword ptr es:[edi]
   12 004114ce 8bf4            mov     esi,esp
   12 004114d0 a110a34100      mov     eax,dword ptr [Sample_Hello!_imp_?endlstdYAAAV?$basic_ostreamDU?$char_traitsDstd (0041a310)]
   12 004114d5 50              push    eax
   12 004114d6 68fc774100      push    offset Sample_Hello!`string' (004177fc)
   12 004114db 8b0d0ca34100    mov     ecx,dword ptr [Sample_Hello!_imp_?coutstd (0041a30c)]
   12 004114e1 51              push    ecx
   12 004114e2 e877fcffff      call    Sample_Hello!ILT+345(??$?6U?$char_traitsDstdstdYAAAV?$basic_ostreamDU?$char_traitsDstd (0041115e)
   12 004114e7 83c408          add     esp,8
   12 004114ea 8bc8            mov     ecx,eax
   12 004114ec ff1508a34100    call    dword ptr [Sample_Hello!_imp_??6?$basic_ostreamDU?$char_traitsDstdstdQAEAAV01P6AAAV01AAV01ZZ (0041a308)]
   12 004114f2 3bf4            cmp     esi,esp
   12 004114f4 e8b5fcffff      call    Sample_Hello!ILT+425(__RTC_CheckEsp) (004111ae)
   13 004114f9 8bf4            mov     esi,esp
   13 004114fb 8d45fb          lea     eax,[ebp-5]
   13 004114fe 50              push    eax
   13 004114ff 8b0d04a34100    mov     ecx,dword ptr [Sample_Hello!_imp_?cinstd (0041a304)]
   13 00411505 51              push    ecx
   13 00411506 ff1500a34100    call    dword ptr [Sample_Hello!_imp_??$?5DU?$char_traitsDstdstdYAAAV?$basic_istreamDU?$char_traitsDstd (0041a300)]
   13 0041150c 83c408          add     esp,8
   13 0041150f 3bf4            cmp     esi,esp
   13 00411511 e898fcffff      call    Sample_Hello!ILT+425(__RTC_CheckEsp) (004111ae)
   14 00411516 33c0            xor     eax,eax
   15 00411518 52              push    edx
   15 00411519 8bcd            mov     ecx,ebp
   15 0041151b 50              push    eax
   15 0041151c 8d1540154100    lea     edx,[Sample_Hello!wmain+0x90 (00411540)]
   15 00411522 e88dfbffff      call    Sample_Hello!ILT+175(_RTC_CheckStackVars (004110b4)
   15 00411527 58              pop     eax
   15 00411528 5a              pop     edx
   15 00411529 5f              pop     edi
   15 0041152a 5e              pop     esi
   15 0041152b 5b              pop     ebx
   15 0041152c 81c4cc000000    add     esp,0CCh
   15 00411532 3bec            cmp     ebp,esp
   15 00411534 e875fcffff      call    Sample_Hello!ILT+425(__RTC_CheckEsp) (004111ae)
   15 00411539 8be5            mov     esp,ebp
   15 0041153b 5d              pop     ebp
   15 0041153c c3              ret

The highlighted line shows, stack pointer has changed and this indicates function allocated some space in stack. So, would like to know how much space has been allocated?

Issued command:

0:000> ? 0CCh
Evaluate expression: 204 = 000000cc
So, function wmain allocated 204(0x0CC) bytes on stack.
Now I’m interested to know where ‘Hello World’ String is. If we look at call stack, there is an entry like below:

12 004114d6 68fc774100      push    offset Sample_Hello!`string' (004177fc)

Executed following command and it displays it content:

0:000> da 004177fc
004177fc  "Hello World"

More to come....
 
Happy Debugging.

Comments

Popular posts from this blog

Reversing char array without splitting the array to tokens

 I was reading about strdup, a C++ function and suddenly an idea came to my mind if this can be leveraged to aid in reversing a character array without splitting the array into words and reconstructing it again by placing spaces and removing trailing spaces. Again, I wanted an array to be passed as a function argument and an array size to be passed implicitly with the array to the function. Assumed, a well-formed char array has been passed into the function. No malformed array checking is done inside the function. So, the function signature and definition are like below: Below is the call from the client code to reverse the array without splitting tokens and reconstructing it. Finally, copy the reversed array to the destination.  For GNU C++, we should use strdup instead _strdup . On run, we get the following output: Demo code

A simple approach to generate Fibonacci series via multi-threading

T his is a very simple approach taken to generate the Fibonacci series through multithreading. Here instead of a function, used a function object. The code is very simple and self-explanatory.  #include <iostream> #include <mutex> #include <thread> class Fib { public:     Fib() : _num0(1), _num1(1) {}     unsigned long operator()(); private:     unsigned long _num0, _num1;     std::mutex mu; }; unsigned long Fib::operator()() {     mu.lock(); // critical section, exclusive access to the below code by locking the mutex     unsigned long  temp = _num0;     _num0 = _num1;     _num1 = temp + _num0;     mu.unlock();     return temp; } int main() {     Fib f;          int i = 0;     unsigned long res = 0, res2= 0, res3 = 0;     std::cout << "Fibonacci series: ";     while (i <= 15) {         std::thread t1([&] { res = f(); }); // Capturing result to respective variable via lambda         std::thread t2([&] { res2 = f(); });         std::thread t3(

Variadic template class to add numbers recursively during compilation

 The idea of having a class to add numbers (variable parameters) during compilation time recursively. Also wanted to restrict types to a single type while sending parameters to class member function. That said, if we mix int, float and double types to add function shall result in compilation error. How do we achieve this. The below is the code which actually helps to achieve this: <code> #include < fmt/format.h > template < typename T> class MyVarSumClass{     private :         T _sum = 0 ;     public :         template < typename ... TRest>         T add(T num, TRest... nums){             static_assert (std::conjunction<std::is_same<TRest, T>...>{}); /* Assert fails                if types are different */             _sum += num;             return add(nums...); // Next parameter packs gets picked recursively         }         // Base case         T add(T num){             _sum += num;             return _sum;         } }; int main() {     My