diff --git a/_layouts/post.html b/_layouts/post.html index 89c16b8..c8d8ffa 100644 --- a/_layouts/post.html +++ b/_layouts/post.html @@ -1,6 +1,9 @@ --- layout: default --- + + +
@@ -32,5 +35,15 @@

Comments

+
diff --git a/_posts/2016-07-31-debugging-ms-word.markdown b/_posts/2016-07-31-debugging-ms-word.markdown index 2667b68..5ba2ba3 100644 --- a/_posts/2016-07-31-debugging-ms-word.markdown +++ b/_posts/2016-07-31-debugging-ms-word.markdown @@ -33,12 +33,12 @@ Using `!uniqstack` immediately gives the reason why Word is hanging: it's waitin ``` The signature of MessageBoxW is: -```C++ +``` int WINAPI MessageBox( _In_opt_ HWND hWnd, _In_opt_ LPCTSTR lpText, _In_opt_ LPCTSTR lpCaption, - _In_ UINT uType);``` It seems that it could be useful to know what the message box is showing, so we need to find the values of parameters lpText and lpCaption. `kp` seems to be able to show parameter values for a frame, but it does not work without private symbols. Too bad. `kb` can show the first three arguments. Let's try that. + _In_ UINT uType)```. It seems that it could be useful to know what the message box is showing, so we need to find the values of parameters lpText and lpCaption. `kp` seems to be able to show parameter values for a frame, but it does not work without private symbols. Too bad. `kb` can show the first three arguments. Let's try that. ``` 0:008> kb @@ -77,7 +77,7 @@ Fixed! ### We need to go deeper Some time later I thought it could be interesting to figure out where we took a wrong turn in our analysis, since it seemed like we stumbled onto the cause of the issue completely by accident. Time to get out our crash dump. -Turns out Windows uses different calling conventions on x86 and x64. WinApi x86 uses _stdcall, which means all function parameters are pushed onto the stack, so parameters of all functions above the current frame stay on the stack (where they can be viewed). On x64, the [calling convention][x64fastcall] is a variation of fastcall, so the first four parameters are passed using the registers rcx, rdx, r8 and r9. In non-optimised builds, the compiler generates code to store these registers on the stack in 20h bytes of 'home space' which must be allocated by a function's caller. With optimisation on, it does whatever it wants to do. [This article][debugging] (see the section "The Nightmare Begins") describes some debugging techniques. +Turns out Windows uses different calling conventions on x86 and x64. WinApi x86 uses _stdcall, which means all function parameters are pushed onto the stack, so parameters of all functions above the current frame stay on the stack (where they can be viewed). On x64, the [calling convention][x64fastcall] is a variation of _fastcall, so the first four parameters are passed using the registers rcx, rdx, r8 and r9. In non-optimised builds, the compiler generates code to store these registers on the stack in 20h bytes of 'home space' which must be allocated by a function's caller. With optimisation on, it does whatever it wants to do. [This article][debugging] (see the section "The Nightmare Begins") describes some debugging techniques. Let's try to find the values passed to MessageBoxW. First, dump its' code.
diff --git a/_posts/2016-08-02-method-calls-clr.markdown b/_posts/2016-08-02-method-calls-clr.markdown
index 95b1d4d..2959e34 100644
--- a/_posts/2016-08-02-method-calls-clr.markdown
+++ b/_posts/2016-08-02-method-calls-clr.markdown
@@ -63,7 +63,7 @@ Here we load the address of an indirection cell -- a pointer-sized value which s
 cmp     dword ptr [rcx],ecx
 ```
 
-Interestingly enough, this actually is a null check (Dereferencing a null pointer will cause an access violation that the runtime will turn into a NullReferenceException. For virtual calls, we dereference the object pointer anyway to get the method table, so an explicit check is not needed. The code that determines if an explicit check needs to be emitted can be found in [`CEEInfo::getCallInfo`][CEEInfo::getCallInfo].
+Interestingly enough, this actually is a null check (Dereferencing a null pointer will cause an access violation that the runtime will turn into a NullReferenceException. For virtual calls, we dereference the object pointer anyway to get the method table, so an explicit check is not needed. The code that determines if an explicit check needs to be emitted can be found in [`CEEInfo::getCallInfo`][CEEInfo::getCallInfo]).
 
 ```nasm
 call    qword ptr [r11]