papers
+HCU papers
courtesy of fravia's page of reverse engineering
28 June 1999
SLH's seventh paper
The Succession

"The second version of the masm32 package is already in circulation and reasonably well received and I am just putting the finishing touches to the third version. At the end of the assay before the ASM template is a pair of links where people who are interested can download the package to try it out."

SLH is back again with another (the seventh) of his small masterpieces: You would be well advised to read all the preceding parts of what is going to be a DEFINITIVE HCU MANUAL INTRODUCING WINDOWS DISASSEMBLING: it's a concentrated very good course about the UTMOST IMPORTANCE of assembling in everyday windows (or whatever) programming. This will help you, among other things :-) in order to better understand the purposes (and the power) of what we are all doing here...

08 May 98 SLH ~ hutch1.htm The supression and resurrection of assembler programming. papers ~fra_0116
16 May 98 SLH ~ hutch_61.htm The Bridge: In Pursuit Of Lost Knowledge papers ~fra_011C
21 May 98 SLH ~ hutquest.htm THE QUEST: Building the launch pad papers ~fra_011F
29 May 98 SLH ~ hutch28.htm Software warriors through the warp papers ~fra_0123
05 June 98 SLH ~ hutch_65.htm The Eye Of The Warrior (a "graphical" windows' paper) papers ~fra_0128
10 June 98 SLH ~ hutchif1.htm The iron fist (Keeping The Crackers Amused) papers ~fra_0129
26 June 1999 SLH ~ hutch_su.htm The Succession papers ~fra_xxxx

And here you go... Enjoy!

papers
+HCU papers
THE SUCCESSION
There has to be a good reason for an ancient warrior to return from a place
in space / time to the modern world of computing and it usually has to do
with the need to again practice the black arts from a time when the world
of computers was young and Billy Gates was just becoming the all American
Mr Nice Guy.
The lack of viable tools for writing quality binary code in 32 bit
assembler has been a hallmark of the sickness inflicted on the general
programming community since Windows 95 was introduced on the market, the
problem of where programs that once showed the speed and vigour of youth
have become sick and bloated as the tools became the toys of children, not
the cutting edge tools of warriors.
The cold steel in the ancient warriors eye looks through the marketing hype
at the fundamental lie of the land and it was here that the real damage
was done when the tools of the ancient black arts no longer worked.
Closed system proprietry information left a hole in the capacity of to
write the new format programs so the black art of writing assembler lived
on only in the memories of the ancient warriors who did battle using them
in the ancient times.
Warriors of a different way arose out of the chaos and re-discovered a part
of the ancient black art and put it to a new and clever use, reverse
engineering the trash that was being peddled to the unsuspecting as
computer programs.
Among the true masters of the new warriors, the pursuit of knowledge with
no taint of squalid gain became the hallmark of their movement that
continues to defy the efforts of the greedy to crush it yet it also gave
rise to the knowledge of part of the ancient black art, the low level
structure of binary files.
For the ancient warrior who had returned in the past in search of clever
things, the corridors of the internet were a desolate and desperate place
where the cries of the ignorant were posted like signposts to destruction.
The precision and power of the past had almost been lost in the hype that
surrounded the garbage that was peddled as development tools, "we have
objects, gimmicks, glitzy front ends, OLE, DDE" but to the eye of the
ancient, there was no power, just the delusion of the ignorant.
For the interim period, there were leftovers of the ancients that sufficed
in keeping the persistent seeker of knowledge with some vestige of  power,
it was an anarchronism in the C and similar compilers that would still
write inline assembler. Although an imperfect vehicle, it was an entry
into the black arts of old.
Often, thing in far away places have subtle yet very influential effects
on the way the rest of the world works. The Microsoft Corporation had not
only succeeded in crushing almost all of its competition
but had also succeeded in becoming a monopoly as well, but in doing so, it
fell foul of another great power, the US Department of Justice, an opponent
that had already left the battered remains of both Standard Oil and IBM
in its wake.
Knowledge of the ancient black arts meant knowing the real tools of the
trade as many of the newer players did not even know what they were and it
was here that the ancient warrior saw the change that was part of the
fallout from the ongoing battle between the Microsoft Corporation and the
Department of Justice.
As a sign of repentence for its past arrogance, the Microsoft Corporation
have posted as free downloads, two of the necessary components to return
to the ancient black arts, the WIN98DDK and the PLATFORMSDK. From the DDK
came version 6.11 of the assembler for MASM which when upgraded with the
version 6.13 patch to be the latest assembler available, ML.EXE 6.13. The
DDK also contained the coff format linker version 5.12.8078 which was also
the latest version available.
From the PLATFORMSDK came the full set of IMPORT libraries so the
necessary tools had again become available. What was missing was
a matching full set of include files as those from the DDK were both
flawed and incomplete.
The breakthrough came in the form of the data about the
imports in the libraries.
Using one of the incomplete but functional include files that had been
available for some time, the linker referenced the import libraries for
parameter numbers and size. The data occurred in the form _FunctionName@12
where the decimal number at the end referred to the number of bytes that
the parameters used when passed.
It just happens to be that almost every windows API function uses :DWORD
size parameters so the conversion of the internal data from the import
libraries to a prototype was a fussy but more or less routine process.
The last great hurdle was an extensive set of equates and structures and
this was done the old hard way as a joint project with another ancient
warrior, Iczelion.
Iczelion is a warrior from a far and exotic land who cut his teeth on
C/C++ compilers and is fluent in both TASM and MASM. From his hand 
has come the best set of tutorials for MASM on the market covering
an important range of topics in 32 bit windows assembler.
There are number of architectures in assembler language programming that
have been used for 32 bit windows. The ground breaking work by Sven B.
Schrieber was very powerful for the available technology but it could not
be described as entry level assembler.
The very influential work of Steve Gibson was an important breakthrough in
that it showed how to make an assembler application that was fundamentally
simple in construction that could be extended without the usual problems
associated with programs that were very hard to read.
The architecture that did have the promise of the age to come was that of
Iczelion. By using MASM's capacity with procedures, a very orthodox
looking "WinMain" and "WndProc" procedures brought assembler
out of the novelty market into the mainstream of 32 bit windows
programming.
One of the many things that pure assembler does well is emulate the
architecture of C. This is an important consideration when writing code
for an operating system that is a fundamentally C style
construction. The main difference between C and ASM is the freedom in ASM to
lay out code design in almost any way that a programmer wishes. The other
of course is that in ASM, the programmer is free of the C runtime libraries
and their overhead.
Ancient warriors are not noted for either their patience or tolerance when
it comes to the tools of the trade and it was here that the need for some
new and small tools arose. Ancient warriors grew up in open architecture
systems and do not trust the closed system approach that the modern IDE
assumes.
When you write code, you write it in an EDITOR, when you assemble it you
use an ASSEMBLER and when you finally link it, you use a
LINKER. For the resources, you use a RESOURCE compiler and in this
way, the programmer is in control of the code that is written, not a prisoner of
the IDE designer and the assumptions that go with it.
This is a formula for a programmable editor that will run external tools
in a convenient way and it is here that ancient warriors
have the experience of the past in that if the tool does not exist, write it.
MASM32 - the new way.
To put enough things together to write assembler in fast and convenient
ways was a problem of logistics. The Microsoft binaries
were available as free downloads which gave the low level tools necessary to
produce the binary files.
The import libraries solved another problem, with the development of the
utility L2INC.EXE, the full set of include files for all of the windows
APIs became a routine production and with the joint project of the equates
and structures in the WINDOWS.INC file being maintained, the rest was just
screwing a new package together.
One of the virtues of ancient warriors writing their own tools and
accessories is that they are not beholding to the financial considerations
of other sources and can use their own tools to build whatever they like.
The birth of the MASM32 package is based on the rights of use being
extended under copyright to any person who wishes to use it
without any form of cost whatsoever.
MASM32 comes as a working programming environment for
writing 32 bit ASM in a fast and convenient way. It needs to be installed
and the libraries need to be added in the correct directory. Once this is
done, the L2INC.EXE utility is run from the include directory which will
build a complete set of include files.
The way of testing if the installation is correct is to start the editor,
QEDITOR.EXE, load the file called TEMPLATE.ASM in the directory called
TEMPLATE and select from the Project menu, the option Build All. If all is
set up correctly, the EXE file is built by compiling the resources,
assembling the code and linking it into a 32 bit portable executable file.
The Code Design.
Almost all of the data for windows APIs comes in C or C++ notation. The
main sources of windows APIs is the WIN32.HLP file. While it is not the only
architecture available, using a C style WinMain and WndProc have a great
advantage in that they are already familiar to a very large body of
programmers who have written API code in windows.
MASM has a very good simulation of certain high level constructions that C
programmers are used to using but without any of the overhead that is
normally associated with the use of a high level language. It can do
runtime comparisons in a very similar way to the traditional C switch
block which can be nested in the normal manner.
MASM will also do a reasonable simulation of function calls using its
"invoke" syntax. The only extra step is that you must get the return value
in eax if you need the function's return value.
Writing a simulation of a function is reasonably straight forward, you
write a proc with the parameters you need, write the code that you want
and place the return value in the eax register with "ret" after it.
Data types.
The similarities stop when it comes to data types, the latest count of
C/C++ data types is now somewhere over 60 yet when you look at the header
files, they reduce down to the three that are determined by the processor
registers, :BYTE :WORD & :DWORD.
Many have approached assembler as an appendage to other languages and in
many respects, have restricted it to the limitations of the other language
but fundamentally, pure assembler is simple if you don't try to cripple
it.
MASM32 treats assembler as a language in its own right and only uses the
generic ASM data types. This factor alone reduces the enormous range of
errors that follow from incorrect data sizes.
MASM has capacities that high level languages do not have. The capacity to
write macros puts the assembler language programmer in a position to
effectively create a new language if that is what is required. Macros in
assembler are one of the very smart ways of improving throughput.
An assembler macro is a form of text expansion where you can pass
parameters to. The following is a very simple macro out of
MASM32.
    return MACRO arg
      mov eax, arg
      ret
    ENDM
This allows the programmer to type,
    return 0
which in turn will be expanded by the assembler to,
    mov eax, 0
    ret
There is no mnemonic to copy memory to memory so a simple macro is used in
MASM32 to do this operation.
    m2m MACRO M1, M2
      push M2
      pop  M1
    ENDM
This allows memory operand copy in a single line of code,
    m2m mVar2, mVar1
which is expanded by the assembler to,
    push mVar1
    pop  mVar2
MASM32 has deliberately avoided using complex macros as they are not
immediately easy to understand yet this capacity is very powerful when it
is understood and used.
The following macro is used to automate calling a DLL by the direct
method.
Using the code,
    calldll
"dllname.dll","ExportFunctionName",par1,par2 etc...
The following code is expanded at assemble time and performs the direct
call to the DLL.
;--------------------------------------------------------------------------
      calldll MACRO
DllName:REQ,FuncName:REQ,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,
                            
p11,p12,p13,p14,p15,p16,p17,p18,p19,p20
        LOCAL lbl       ;; assembler replaces LOCAL
variables
        LOCAL LibName   ;; with a unique ID so that
the macro
        LOCAL ProcName  ;; can be called more than
once.
        LOCAL ByPass
        LOCAL TheEnd
        jmp lbl
          LibName       db DllName,0
          ProcName      db FuncName,0
        lbl:
        ;; -------------------------------------------
        ;; loop through parameters backwards and
        ;; push non blank ones onto the stack
        ;; -------------------------------------------
        FOR
arg,<p20,p19,p18,p17,p16,p15,p14,p13,p12,p11,\
                 p10,p9,p8,p7,p6,p5,p4,p3,p2,p1>
          IFNB <arg>    ;; If not blank
            push arg    ;; push parameter
          ENDIF
        ENDM
        mov  eax, offset LibName  ;; parameter for
LoadLibrary
        push eax
        call LoadLibrary
        cmp  eax, 0               ;; if function fails
        je   TheEnd               ;; don't process
others
        mov  edx, offset ProcName ;; use edx so as to
not change eax
        push edx
        push eax                  ;; module handle
from LoadLibrary
        mov  esi, eax             ;; store it in esi
        call GetProcAddress       ;; DLL function
address returned in eax
        cmp  eax, 0               ;; if function fails
        je   ByPass               ;; don't call DLL
function
        call eax                  ;; call the function
in DLL
      ByPass:
        push eax                  ;; function return
or 0 from
GetProcddress
        push esi                  ;; push module
handle onto stack
        call FreeLibrary
        pop eax                   ;; pop function
return value
      TheEnd:
      ENDM
;------------------------------------------------------------------------
It is worth noting that the above macro contains error
checking of the
return values of some of the functions which makes the
code slightly
larger than it should be. The experienced programmer
would simply pass the
correct values to the macro and save the increase in
code size. In the
development stage, there may be some value of having
two different macros
available, one for development and the other for the
release version.
Macros of this complexity and many others like it are
among the capacity
that the assembler programmer has at their disposal
and this is one of the
ways that ASM programmers dramatically improve their
throughput of code,
the difference is that it is still pure assembler, not
some bloated bag of
junk.
A consideration in the design of MASM32 is that it
will be run on
computers
that already have other programming languages
installed on them which have
various environment settings set up for their own
requirements. MASM32
uses
no environment settings and specifies the full paths
and names of any
binary or text file that it uses.
This consideration requires a little more typing but
it ensures that the
correct include files and libraries are used. The
following example is the
normal way of using the matching include files and
libraries in MASM32.
      include drv:\masm32\include\windows.inc
      include drv:\masm32\include\user32.inc
      include drv:\masm32\include\kernel32.inc
      includelib drv:\masm32\lib\user32.lib
      includelib drv:\masm32\lib\kernel32.lib
The bare mimimum code for a working exe file in MASM32
is smaller than
many
would think. Without the declarations it is as
follows,
;
#########################################################################
    .code
start:
    jmp @F
      szDlgTitle    db "Minimum MASM",0
      szMsg         db "  --- MASM Pure and Simple ---
 ",0
    @@:
    invoke MessageBox,0,ADDR szMsg,ADDR
szDlgTitle,MB_OK
    invoke ExitProcess,0
end start
;
#########################################################################
This amazing piece of bloatware assembles at 1536
bytes as a working
portable executable file. Posted at the end of this
document is a full
working template for a win32asm program that assembles
at 11264 bytes. It
has a toolbar, multi-part status bar, common dialog
support for file Open
and Save and its similarity to code written in proper
C for windows is
intentional.
MASM32 is aimed at programmers who among other things,
have a background
in
writing windows code in C, Basic & Pascal compilers
who are interested in
migrating some of their coding into pure assembler.
The architecture of
writing ASM code in a familiar and convenient way is
not only far more
productive, it assembles without size or performance
penalty to ASM code
that is written like an assembler dump.
The capacity to write assembler in a similar manner to
a high level
language
has economies in code design that actually make the
program either smaller
or faster or both.
IS THERE LIFE AFTER CRACKING ?
This may have a lot to do with what is on television
for the next few
months but boredom is a serious problem for those who
have developed the
skills of healing sick software and have nowhere else
left to go. Its like
building a rocketship but having it locked in your
garage.
There is a solution to post cracking depression,
instead of being trapped
in a maze of garbage looking for that elusive byte or
whatever, take the
next step and craft a program or two that has none of
the irritations of
the junk that you are used to shovelling through.
The brain of the cracker is well equiped to take the
next step into
writing
pure assembler as the attention to detail necessary to
write assembler is
already there, what is needed is the capacity to
impliment an architecture
that can be extended with elegance and efficiency and
this just takes
practice.
THE ANCIENTS
For those many ancient warriors who have put their
hand to the succession
of the black arts to the next generation, a small
treat is in order as a
gesture of honour between ancient warriors across
space / time, select one
of your favourite pure malts, a smooth dry highland
malt if you are in a
hot and dry land, perhaps a good Islay or Orkney malt
if your place in
space / time is cold and windy and "Salute", the
succession has started.
Now for the young guys, one of the secrets of writing
elegant and fast
assembler is the knowledge of what constitutes a good
malt and how to use
it. The correct balance will see the production of
binary of true
excellence, get it wrong and your wits will fade from
you. Ancient
warriors
have spent many years perfecting this balance.
The tools are now in your hands to write software that
has the virility
and
speed of youth, make sure it is worthy of the ancient
warriors that worked
to pass it down to you.
THE SUCCESSION
                              ---===o===---
MASM32 and the import libraries can be downloaded from
either of the two
following sites. The excellent set of tutorials
written by Iczelion can be
downloaded from the first address.
http://win32asm.cjb.net
http://www.pbq.com.au/home/hutch/masm.htm
;
@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@
;
;                               MODEL.ASM
;                               ~~~~~~~~~
; This template is designed for a larger architecture
application which
; has a separate include file for its local prototypes
and .data section.
;
; It uses a tool bar technique which is easier to
modify & extend and it
; uses a multi-part status bar for displaying
different values at the same
; time. It also has standard File Open & File Save
common dialog boxes.
;
@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@
      .386
      .model flat, stdcall  ; 32 bit memory model
      option casemap :none  ; case sensitive
      include model.inc     ; local includes for this
file
;
#########################################################################
.code
start:
      invoke GetModuleHandle, NULL
      mov hInstance, eax
      invoke GetCommandLine
      mov CommandLine, eax
      invoke InitCommonControls
      invoke
WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
      invoke ExitProcess,eax
;
#########################################################################
WinMain proc hInst     :DWORD,
             hPrevInst :DWORD,
             CmdLine   :DWORD,
             CmdShow   :DWORD
      ;====================
      ; Put LOCALs on stack
      ;====================
      LOCAL wc   :WNDCLASSEX
      LOCAL msg  :MSG
      LOCAL Wwd  :DWORD
      LOCAL Wht  :DWORD
      LOCAL Wtx  :DWORD
      LOCAL Wty  :DWORD
     
;==================================================
      ; Fill WNDCLASSEX structure with required
variables
     
;==================================================
      invoke LoadIcon,hInst,500    ; icon ID
      mov hIcon, eax
      mov wc.cbSize,         sizeof WNDCLASSEX
      mov wc.style,          CS_HREDRAW or CS_VREDRAW
\
                             or CS_BYTEALIGNWINDOW
      mov wc.lpfnWndProc,    offset WndProc
      mov wc.cbClsExtra,     NULL
      mov wc.cbWndExtra,     NULL
      m2m wc.hInstance,      hInst
      mov wc.hbrBackground,  COLOR_BTNFACE+1
      mov wc.lpszMenuName,   NULL
      mov wc.lpszClassName,  offset szClassName
      m2m wc.hIcon,          hIcon
        invoke LoadCursor,NULL,IDC_ARROW
      mov wc.hCursor,        eax
      m2m wc.hIconSm,        hIcon
      invoke RegisterClassEx, ADDR wc
      ;================================
      ; Centre window at following size
      ;================================
      mov Wwd, 500
      mov Wht, 350
      invoke GetSystemMetrics,SM_CXSCREEN
      invoke TopXY,Wwd,eax
      mov Wtx, eax
      invoke GetSystemMetrics,SM_CYSCREEN
      invoke TopXY,Wht,eax
      mov Wty, eax
      szText szClassName,"Template_Class"
      invoke CreateWindowEx,WS_EX_LEFT,
                            ADDR szClassName,
                            ADDR szDisplayName,
                            WS_OVERLAPPEDWINDOW,
                            Wtx,Wty,Wwd,Wht,
                            NULL,NULL,
                            hInst,NULL
      mov   hWnd,eax
      szText stTxt1," Advanced MASM32 template"
      invoke SendMessage,hStatus,SB_SETTEXT,3,ADDR
stTxt1
      invoke LoadMenu,hInst,600  ; menu ID
      invoke SetMenu,hWnd,eax
      invoke ShowWindow,hWnd,SW_SHOWNORMAL
      invoke UpdateWindow,hWnd
      ;===================================
      ; Loop until PostQuitMessage is sent
      ;===================================
    StartLoop:
      invoke GetMessage,ADDR msg,NULL,0,0
      cmp eax, 0
      je ExitLoop
      invoke TranslateMessage, ADDR msg
      invoke DispatchMessage,  ADDR msg
      jmp StartLoop
    ExitLoop:
      return msg.wParam
WinMain endp
;
#########################################################################
WndProc proc hWin   :DWORD,
             uMsg   :DWORD,
             wParam :DWORD,
             lParam :DWORD
    LOCAL caW :DWORD
    LOCAL caH :DWORD
    LOCAL Rct :RECT
    LOCAL tbab:TBADDBITMAP
    LOCAL tbb :TBBUTTON
    LOCAL sbParts[4] :DWORD
    .if uMsg == WM_COMMAND
    ;======== toolbar commands ========
        .if wParam == 50
            szText tb1,"Button 1"
            invoke MessageBox,hWin,ADDR tb1,ADDR
szDisplayName,MB_OK
        .elseif wParam == 51
            szText tb2,"Button 2"
            invoke MessageBox,hWin,ADDR tb2,ADDR
szDisplayName,MB_OK
        .elseif wParam == 52
            szText tb3,"Button 3"
            invoke MessageBox,hWin,ADDR tb3,ADDR
szDisplayName,MB_OK
        .elseif wParam == 53
            szText tb4,"Button 4"
            invoke MessageBox,hWin,ADDR tb4,ADDR
szDisplayName,MB_OK
        .elseif wParam == 54
            szText tb5,"Button 5"
            invoke MessageBox,hWin,ADDR tb5,ADDR
szDisplayName,MB_OK
        .elseif wParam == 55
            szText tb6,"Button 6"
            invoke MessageBox,hWin,ADDR tb6,ADDR
szDisplayName,MB_OK
    ;======== menu commands ========
        .elseif wParam == 1000
           jmp @F
             szTitleO   db "Open A File",0
             szFilterO  db "All files",0,"*.*",0,
                           "Text files",0,"*.TEXT",0,0
           @@:
           invoke FillBuffer,ADDR szFileName,length
szFileName,0
           invoke GetFileName,hWin,ADDR szTitleO,ADDR
szFilterO
           cmp szFileName[0],0   ;<< zero if cancel
pressed in dlgbox
           je @F
           ; file name returned in szFileName
           invoke MessageBox,hWin,ADDR szFileName,
                             ADDR szDisplayName,MB_OK
           @@:
        .elseif wParam == 1001
           jmp @F
             szTitleS   db "Save file as",0
             szFilterS  db "All files",0,"*.*",0,
                           "Text files",0,"*.TEXT",0,0
           @@:
           invoke FillBuffer,ADDR szFileName,length
szFileName,0
           invoke SaveFileName,hWin,ADDR szTitleS,ADDR
szFilterS
           cmp szFileName[0],0   ;<< zero if cancel
pressed in dlgbox
           je @F
           ; file name returned in szFileName
           invoke MessageBox,hWin,ADDR szFileName,
                             ADDR szDisplayName,MB_OK
           @@:
        .elseif wParam == 1010
            invoke
SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL
        .elseif wParam == 1900
            szText AboutMsg,"MASM32 Pure Assembler
Template",13,10,\
            "Copyright © MASM32 1999"
            invoke ShellAbout,hWin,ADDR
szDisplayName,ADDR AboutMsg,hIcon
        .endif
    ;====== end menu commands ======
    .elseif uMsg == WM_SYSCOLORCHANGE
        invoke Do_ToolBar,hWin
    .elseif uMsg == WM_CREATE
        invoke Do_ToolBar,hWin
        invoke CreateStatusWindow,WS_CHILD or
WS_VISIBLE or \
                                  SBS_SIZEGRIP,NULL,
hWin, 200
        mov hStatus, eax
      ; -------------------------------------
      ; sbParts is a DWORD array of 4 members
      ; -------------------------------------
        mov [sbParts + 0],  100    ; 1st member,
pixels from edge
        mov [sbParts + 4],  200    ; 2nd member,
pixels from edge
        mov [sbParts + 8],  300    ; 3rd member,
pixels from edge
        mov [sbParts +12],   -1    ; 4th member,
furthest right side
        invoke SendMessage,hStatus,SB_SETPARTS,4,ADDR
sbParts
    .elseif uMsg == WM_SIZE
        invoke SendMessage,hToolBar,TB_AUTOSIZE,0,0
        invoke MoveWindow,hStatus,0,0,0,0,TRUE
    .elseif uMsg == WM_CLOSE
        szText TheText,"Please Confirm Exit"
        invoke MessageBox,hWin,ADDR TheText,ADDR
szDisplayName,MB_YESNO
          .if eax == IDNO
            return 0
          .endif
    .elseif uMsg == WM_DESTROY
        invoke PostQuitMessage,NULL
        return 0
    .endif
    invoke DefWindowProc,hWin,uMsg,wParam,lParam
    ret
WndProc endp
;
########################################################################
TopXY proc wDim:DWORD, sDim:DWORD
    shr sDim, 1      ; divide screen dimension by 2
    shr wDim, 1      ; divide window dimension by 2
    mov eax, wDim    ; copy window dimension into eax
    sub sDim, eax    ; sub half win dimension from
half screen dimension
    return sDim
TopXY endp
;
########################################################################
GetFileName proc
hParent:DWORD,lpTitle:DWORD,lpFilter:DWORD
    mov ofn.lStructSize,        sizeof OPENFILENAME
    m2m ofn.hWndOwner,          hParent
    m2m ofn.hInstance,          hInstance
    m2m ofn.lpstrFilter,        lpFilter
    m2m ofn.lpstrFile,          offset szFileName
    mov ofn.nMaxFile,           sizeof szFileName
    m2m ofn.lpstrTitle,         lpTitle
    mov ofn.Flags,              OFN_EXPLORER or
OFN_FILEMUSTEXIST or \
                                OFN_LONGNAMES
    invoke GetOpenFileName,ADDR ofn
    ret
GetFileName endp
;
#########################################################################
SaveFileName proc
hParent:DWORD,lpTitle:DWORD,lpFilter:DWORD
    mov ofn.lStructSize,        sizeof OPENFILENAME
    m2m ofn.hWndOwner,          hParent
    m2m ofn.hInstance,          hInstance
    m2m ofn.lpstrFilter,        lpFilter
    m2m ofn.lpstrFile,          offset szFileName
    mov ofn.nMaxFile,           sizeof szFileName
    m2m ofn.lpstrTitle,         lpTitle
    mov ofn.Flags,              OFN_EXPLORER or
OFN_LONGNAMES
    invoke GetSaveFileName,ADDR ofn
    ret
SaveFileName endp
;
########################################################################
FillBuffer proc
lpBuffer:DWORD,lenBuffer:DWORD,TheChar:BYTE
    push edi
    mov edi, lpBuffer   ; address of buffer
    mov ecx, lenBuffer  ; buffer length
    mov  al, TheChar    ; load al with character
    rep stosb           ; write character to buffer
until ecx = 0
    pop edi
    ret
FillBuffer endp
;
########################################################################
SetBmpColor proc hBitmap:DWORD
    LOCAL mDC       :DWORD
    LOCAL hBrush    :DWORD
    LOCAL hOldBmp   :DWORD
    LOCAL hReturn   :DWORD
    LOCAL hOldBrush :DWORD
      invoke CreateCompatibleDC,NULL
      mov mDC,eax
      invoke SelectObject,mDC,hBitmap
      mov hOldBmp,eax
      invoke GetSysColor,COLOR_BTNFACE
      invoke CreateSolidBrush,eax
      mov hBrush,eax
      invoke SelectObject,mDC,hBrush
      mov hOldBrush,eax
      invoke GetPixel,mDC,1,1
      invoke ExtFloodFill,mDC,1,1,eax,FLOODFILLSURFACE
      invoke SelectObject,mDC,hOldBrush
      invoke DeleteObject,hBrush
      invoke SelectObject,mDC,hBitmap
      mov hReturn,eax
      invoke DeleteDC,mDC
      mov eax,hReturn
    ret
SetBmpColor endp
;
########################################################################
Do_ToolBar proc hWin :DWORD
    LOCAL bSize :DWORD
    LOCAL tbab  :TBADDBITMAP
    LOCAL tbb   :TBBUTTON
    szText tbClass,"ToolbarWindow32"
    invoke CreateWindowEx,0,
                          ADDR tbClass,
                          ADDR szDisplayName,
                          WS_CHILD or WS_VISIBLE,  ;
or TBSTYLE_FLAT,
                          0,0,500,40,
                          hWin,NULL,
                          hInstance,NULL
    mov hToolBar, eax
    invoke
SendMessage,hToolBar,TB_BUTTONSTRUCTSIZE,sizeof
TBBUTTON,0
    ; ---------------------------------------
    ; Put width & height of bitmap into DWORD
    ; ---------------------------------------
    mov  ecx,25  ; loword = bitmap Width
    mov  eax,25  ; hiword = bitmap Height
    shl  eax,16
    mov  ax, cx
    mov bSize, eax
    invoke
SendMessage,hToolBar,TB_SETBITMAPSIZE,0,bSize
    ; ------------------
    ; the toolbar bitmap
    ; ------------------
    invoke LoadBitmap,hInstance,750
    mov hTbBmp,eax
    invoke SetBmpColor,hTbBmp
    mov hTbBmp,eax
    mov tbab.hInst, 0
    m2m tbab.nID,   hTbBmp
    invoke SendMessage,hToolBar,TB_ADDBITMAP,12,ADDR
tbab
    invoke
SendMessage,hToolBar,TB_SETBUTTONSIZE,0,bSize
    mov tbb.fsState,   TBSTATE_ENABLED
    mov tbb.dwData,    0
    mov tbb.iString,   0
    mov tbb.iBitmap,   0
    mov tbb.idCommand, 0
    mov tbb.fsStyle,   TBSTYLE_SEP
    invoke SendMessage,hToolBar,TB_ADDBUTTONS,1,ADDR
tbb
    mov tbb.iBitmap,   0
    mov tbb.idCommand, 50
    mov tbb.fsStyle,   TBSTYLE_BUTTON
    invoke SendMessage,hToolBar,TB_ADDBUTTONS,1,ADDR
tbb
    mov tbb.iBitmap,   1
    mov tbb.idCommand, 51
    mov tbb.fsStyle,   TBSTYLE_BUTTON
    invoke SendMessage,hToolBar,TB_ADDBUTTONS,1,ADDR
tbb
    mov tbb.iBitmap,   2
    mov tbb.idCommand, 52
    mov tbb.fsStyle,   TBSTYLE_BUTTON
    invoke SendMessage,hToolBar,TB_ADDBUTTONS,1,ADDR
tbb
    mov tbb.iBitmap,   0
    mov tbb.idCommand, 0
    mov tbb.fsStyle,   TBSTYLE_SEP
    invoke SendMessage,hToolBar,TB_ADDBUTTONS,1,ADDR
tbb
    mov tbb.iBitmap,   3
    mov tbb.idCommand, 53
    mov tbb.fsStyle,   TBSTYLE_BUTTON
    invoke SendMessage,hToolBar,TB_ADDBUTTONS,1,ADDR
tbb
    mov tbb.iBitmap,   4
    mov tbb.idCommand, 54
    mov tbb.fsStyle,   TBSTYLE_BUTTON
    invoke SendMessage,hToolBar,TB_ADDBUTTONS,1,ADDR
tbb
    mov tbb.iBitmap,   5
    mov tbb.idCommand, 55
    mov tbb.fsStyle,   TBSTYLE_BUTTON
    invoke SendMessage,hToolBar,TB_ADDBUTTONS,1,ADDR
tbb
    ret
Do_ToolBar endp
;
########################################################################
end start



papers
+HCU papers
redhomepage red links red anonymity red+ORC redstudents' essays redacademy database
redantismut redtools redbots & agents reversing redcocktails redjavascript wars redsearch_forms redmail_fravia
redIs reverse engineering illegal?