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
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 (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
You are deep inside fravia's page of reverse engineering,
choose your way out:
homepage
links
anonymity
+ORC
students' essays
academy database
tools
cocktails
antismut CGI-scripts
search_forms
mail_fravia
Is reverse engineering legal?