MemMonitor95 Standard 4.0  and its ThunkConnect32 relations
(Half-crippled program / Unhiding an hidden window / Thunk vagaries)
by FootSteps
(24 November 1997, slightly edited by fravia+)
 Courtesy of fravia's page 
of reverse engineering
Courtesy of fravia's page 
of reverse engineering
       
Well, thunking (thunking up, thunking down, thunkconnect...) was about time to have a 
look at these thunks, don't you believe? Besides there is some 'intuition and luck' in this essay 
and, moreover, I like quite a lot little jewels like the following one:
bpx CreateWindowExA do "dd *((ss:esp)+8)
     With that, each CreateWindowExA hooked by Winnie will show us the second
     parameter we need : lpClassName in the data window.
This kind of info is, IMHO, what makes an essay valuable for us: the targets 
are completely irrelevant... but the knowledge... Ahh, the knowledge... I could 
carry on drinking more and more of it, sitting here and awaiting a slow dawn that 
still hides inside the heavy clouds of november...
MemMonitor95 Standard Edition 4.0  and its ThunkConnect32 relations 
Half-crippled program / Hidden window / Thunked.
================================================
You'll need :
MemMonitor 95 Standard Trial 4.0 from Prudens http://www.spywindows.com/
MemMonitor 95 Professional Trial from Prudens ibidem
Winnie 3.01 to 3.22 (everywhere on the web)
BRW 4.5 to 5.2      (everywhere on the web)
Winsight 5.x        (everywhere with BC++5)
WDasm32 8.x         (everywhere on the web, use 8.9)
IDA 3.7             (everywhere on the web, don't miss it)
Windoze95           (everywhere on your HD)
Once upon a time I was cracking some interesting tools of the trade, the 
Prudens's trial toolz, (see below for a quick easy reversing snippet about 
ExeSpy95 and ComSpy95), when I found in the third one, MemMonitor95, 
a different protection scheme from the two others.
I thought at first: "oh, no... back to trace", but I was happy: it was 
a good thing: I was beginning to bore myself without challenges.
Running the program, memmon95.exe, I was awaiting like with Exespy95 or
ComSpy95 a "sympathic" nag with something like 'Enter the drive where 
your registration key file is' (with these kind of nags sharewares you 
know immediately that the target is reversed! :-) but... here there was 
no sympathic nag.
Instead, a enormous bitmapped screen nag, with a irritating 'unregistered
user', and a very frustrating 'Not all hooks are available in this version'. 
Followed by a classic MessageBox with program presentation and bazaar.
In spite of my irritation, I played a little with memmon95.exe, you know 
we must always spy all the hints of the targets: where are placed on screen 
words like  'unregistered', when the NagMessageBoxes happen, what functions 
are disabled, etc...
This memmon95.exe is a nice tool, a little better than TechFacts to follow 
memory heap calls, because it show you these in real time (with TechFacts you 
must refresh).
I did not have to wait long in order to have my awaited nagscreen: I clicked 
on a Heap captured valor, and bingo! a nag with 
'This function is restricted to... etc, etc...'
I just thought: ha ha ha!, Gotcha! I will fire Winnie, put a classic
bpx MessageBoxA, press some F12 key, and land in a JZ opcode.
Yes, you can try. Fire Winnie. Bpx MessageBoxA. Click on the ListBox 
which makes the nag appear. 
You land obviously in User32!MessageboxA section.
But Press F12. Just once, go ahead.
You see where you land?
Yes, you land in the terrible Kernel32!ThunkConnect32!
Like quicksand! Aaargh!
You can continue to press the F12 key. But you will sink more and more!
Press it 12 times, and you'll land inside... nothing! The darkest codewoods!
Because we have lost hand of Winnie's trace and we sprang back to Windows' 
normal execution...
Well, I jumped on the Win32 SDK. 
What the hell is this ThunkConnect32 API anyway? 
You won't find it in the SDK. You'll find it in the help files:
Windows's developer guide (Borland C++) or in the Microsoft Programmer's
guide to Windows 95 (Borland C++ Builder, M$VC++, and others compilers...).
If you want more information, you've only got a ridiculous article on it 
in the M$ Knowledge Base, and a serious one inside the 'guru' Schulmann's 
book 'Unauthorized Windoze95'. My! You would never believe HOW MUCH 
undocumented is this whole windoze bazaar!
It was the first time I met this API following our paths. 
In fact 'Thunking' is the relation between 32bits and 16bits applications, 
either executables or DLL.
And WindoZ95 makes indeed an overbloated use of that, especially with the 
User32 to the old User interface... You know, W95 swap all time from 32 
to 16bits, from 16bits to 32... Seems sometimes that Windows95 is in fact 
the worse monstrous shareware ever programmed... :-)
So, why could we not get the hand back to Winnie, after this thunk? Who knows?
First, probably because of the MeMonitor95 hooks. You see, MemMonitor hooks
when running some 16/32bits API like GlobalAlloc and GlobalRealloc for example,
ensuring to catch some old WindoZ31 applications, then calls ThunkConnect to
switch from 32bits OS to 16bits.
Second, probably too, because after the nagscreen, and after the ThunkConnect32
Kernel section, the system goes back in the WndProc of the program, more
exactly inside the switch(message) loop. 
Then, we intercept one, which displayed the nag, and the program is now waiting 
some other ones (for example, when you click on some functions of the program). 
Like it is waiting, and not running.
Winnie sleeps. Try, after landing in Kernel!ThunkConnect32, to press F12 a
little times: you will not land inside User32... you'll dwell inside the 'old' 
16bits User!WaitMessage boring loops.
Since I couldn't trace anymore, I disassembled memmon95.exe with W32Dasm.
Well, I found quickly the right MessageBoxA references looking for
'this function is restricted...'. 
Yes, actually several references.
And looking closer to the dead-listing, it seems that that nag happens when
you click on some interesting function : A nag when you want to print, a nag 
when you want to heap process click, a nag when you want to save...
When you want to save? Hey, that isn't at all inside the buttons of 
the trial version!
It was time for a deeper examination of this thunked executable with BRW.
I fired therefore the heavy artillery: Borland Resource Workshop. 
More exactly, with version 5, run your compiler and open memmon95.exe using 
edit resources as a viewer.
And a lot of interesting things should appear in front of your child'eyes:
The enormous bitmap which serves as nag intro.
A registration window.
A registration window?? Well, then...
But wait... you better wait before crying victory. 
Something was terribly wrong.
Yes, I know something was wrong because I already spyed the OTHER 
executable (cracked below), ExeSpy95. 
And ExeSpy95 got TWO NagBitmapScreens.
And the file we study, memmon95.exe, has only ONE NagBitmapScreen. 
A big one with  the sad message 'No hooks are available' printed on it.
ExeSpy95 had the same, AND another one, without any inscriptions, the 
good one, the one we want: the registered one.
Perhaps memmon95 could then paint over these words with a FillRect() or 
some other graphic tricks in order to cover the bitmap when registered? 
No, Let's not be ridiculous... :-)
At this point, I had big doubts about cracking this target. 
Seems that it was a "really crippled" trial version... and that 
there were nothing to do.
But I continued a little. You know, for the fun, never give up!
And I fired Winsight, the window spy utility of the Borland C++.
And looked closer, once more, to my "MEMMON95" DialogBox.
Mmm, I verified all of my target, all the buttons, the ListBoxes, the
EditBoxes...
Suddenly, I jumped! 
In the Winsight detail, a second main window "MEMMON95" appeared!
Open it : you can remark all other child windows: a StatusBar one, a TBar one,
a Client one...
But all have the "hidden" attribute. This is why we just see the DialogBox.
I got an idea and looked at the readme.1st file that come with this appz 
(This is what I should have done from the beginning...)
There are two version of MemMonitor : the standard (we're studying)
and the Professional. I read :
STANDARD vs PROFESSIONAL (for Windows 95)
=========================================
The Professional Edition provides some advanced features:
  1. a view/log window is provided that displays captured calls
     - you can print the log
     - you can save the log to a file
  2. a setting window is provided that you can disable those APIs you are not
     interested
Well, the Pro version provides a view/log window? 
And what about the hidden window which lurk when we run the standard 
MemMonitor?
I then immediately wanted to un-hide this window. 
But it is not possible to change attributes when an application is 
running.
By the way, (Little digression about reversing MemMonitor95 with IDA 3.7 and W32Dasm8.9
There's a lot of the memmon95.exe code which would be interesting to see,
but let's just take one example: when you click on the 'Heap captured for the
process' ListBox. You remember, we've got a pretty nag then, with 'this 
function is...'
Well, I first reverse memmon95.exe with W32Dasm8.9. 
You find quickly that the nag is at :
:0040C1FD E96D050000              jmp 0040C76F                  ; a jmp here???
:0040C202 8B4510                  mov eax, dword ptr [ebp+10]   ; begin of the proc.
:0040C205 C1E810                  shr eax, 10
:0040C208 25FFFF0000              and eax, 0000FFFF
:0040C20D 25FFFF0000              and eax, 0000FFFF
:0040C212 83F801                  cmp eax, 00000001
:0040C215 7534                    jne 0040C24B
:0040C217 8D8D50FDFFFF            lea ecx, dword ptr [ebp+FFFFFD50]
:0040C21D 51                      push ecx
:0040C21E 8D9510FCFFFF            lea edx, dword ptr [ebp+FFFFFC10]
:0040C224 52                      push edx
:0040C225 A1CCAE4100              mov eax, dword ptr [0041AECC]
:0040C22A 50                      push eax
:0040C22B E88BC8FFFF              call 00408ABB
:0040C230 6830300000              push 00003030
:0040C235 8D8D50FDFFFF            lea ecx, dword ptr [ebp+FFFFFD50]
:0040C23B 51                      push ecx
:0040C23C 8D9510FCFFFF            lea edx, dword ptr [ebp+FFFFFC10]
:0040C242 52                      push edx
:0040C243 6A00                    push 00000000
:0040C245 FF1554E64100            Call USER32.MessageBoxA         ; nagscreen
If you put a breakpoint on the 'begin of the proc' location I've marked,
and clicking on it in MemMonitor95, SoftIce will obviously break in 40C202.
But look what's above this 40C202 :
:0040C1FD E96D050000              jmp 0040C76F
What? A jmp? Then how could we land at the line just after?
Code self modifying? No, scroll a little in Winnie when reaching this
breakpoint,
you see that above the 40C202, the jmp is right here.
Then?
Then, as we learned, never believe what you see. 
What is faked here is that W32Dasm hasn't put its 
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses...
as usual.
Then I thought : well, this is the procedure of the ListBox item of the
memmon95.exe. Perhaps the program change it when running with some API like
'SetProcAdress'. But there wasn't some of that. Then I lost a mad time to
search... 
To understand what's going on very quickly: let's reverse memmon95.exe with IDA.
You got at the same location :
40C1FDF         jmp     loc_40C76F      ; a jmp here?
; -----------------------------------------------------------------------
loc_40C202:				; CODE XREF: .text:0040BECFu  ; HERE!
					; DATA XREF: .text:0040C7B0o
		mov	eax, [ebp+10h]
		shr	eax, 10h
                ...
		call	ds:MessageBoxA  ; nagscreen
And you see, IDA has correctly reversed (and found) the caller at 0040BECF.
The DATA XREF: .text:0040C7B0 point to the different locations called
by this ListBox procedure :
off_40C7AC	dd offset loc_40BEFA	; DATA XREF: .text:0040BECFr
		dd offset loc_40C202    ; HERE is the one we study!
		dd offset loc_40C250
		dd offset loc_40C3FB
		dd offset loc_40C491
		dd offset loc_40C76F
We are in the 'Call Relocation Table', by the way (a great essay 
from fravia+, read it!
Well, let's go to the caller, from our 40C202 location I repeat here :
loc_40C202:				; CODE XREF: .text:0040BECFu  ; HERE!
					; DATA XREF: .text:0040C7B0o
		mov	eax, [ebp+10h]
We land in :
40BECF          jmp      ds:off_40C7AC[edx*4]
This jmp choose the right procedure to jmp in regard of the edx valor.
IDA is a little boring coz it is DOS based and not very comfortable to 
use when debugging WindoZ programs. The interface is a little old and 
less comfortable to use than W32Dasm... but IDA 3.7 EXPLODES, literally, 
poor W32Dasm 8.9!
I was a little suspicious, at the beginning... I am not any more. No
wonder IDA has been chosen as the +HCU 'official' disassembler!
It is indeed very strong for us 'reversers' that we can, dead-listing, 
see an 'indexed-based reference' starting from a complex 
jmp ds:off_40C7AC[edx*4]!
Bravo Ilfak! Let's now wait the same approach (windozed) from PJ Urbanik...
Little snippet about others Prudens' targets: ExeSpy95 4.41 and ComSpy95 4.41 :
First, install ExeSpy95. 
Deadlist it:
Replace the
:004078B1 FF151C064200            Call USER32.DialogBoxParamA
which is the dialogBox asking you to choose the drive where is 
your registered file by :
:004078B1 E941060000              jmp 00407EF7
This jmp will register you, but now:
:00407F25 FF150C064200            Call USER32.MessageBoxA
which is the Nag saying you that you've got '0 days left'... 
with three 'inc eax ; dec eax'.
Same boring protection scheme with ComSpy95.
If these tools of the trades interest you.
Cya.
--FootSteps.
(c) FootSteps  All rights reversed