673 lines
34 KiB
Plaintext
673 lines
34 KiB
Plaintext
|
|
Introduction To Win95 Cracking
|
|
|
|
Introduction to Win95 Cracking
|
|
|
|
A few words before beginning
|
|
|
|
Giving credits, where credit is due ! So, i'd like to give a really BIG
|
|
thanks to ED!SON of United Cracking Force for his tutorial about
|
|
Windows 95 cracking, without it i won't be here telling you how to
|
|
crack a program under win 95.
|
|
Giving ALL the credits... all i learned about cracking is with the help
|
|
of great tutorials : 5 Minutes 4 a Crack /NeverOne, Amateur Crackist
|
|
Tutorial /Specular Vision, Cracking for Masses /FraVia, Old Red Cracker
|
|
Tutorials /+ORC (A Must), The Ancient Art Of Cracking & Cracking 101
|
|
/Buckaroo Banzai, The Cracking Manual /Cyborg, The Uncle Joe CrackBook
|
|
/Uncle Joe (heh, what did you expect ?). But also with 40 Hex
|
|
Magazines, The Crypt Newsletters, Virus Laboratories And Distribution.
|
|
Note : a lot of the explaination i'll give you in Introduction parts
|
|
are ripped from some tutorials upper, it's because i wanted to have
|
|
something complete you can start with. Tnx again to those who wrot'em.
|
|
|
|
For this tutorial you'll need :
|
|
ACDSee32 V2.0 Beta
|
|
Soft-Ice 3.00
|
|
HexWorkShop
|
|
|
|
Introduction to Cracking
|
|
|
|
You might be wondering what type of programming skills you need to
|
|
become a cracker. Knowing a higher level language such as Basic,
|
|
Pascal, or C++ will help you somewhat in that you will have an
|
|
understanding of what's involved in the process of writing a program
|
|
and how certain aspects of a program function. If you don't have any
|
|
programming skills, you have a long road ahead of you. But even if you
|
|
can program in a high level language, in order to crack you have to
|
|
know assembly... It really doesn't matter what language a program was
|
|
written in in order to crack it, because all programs do the same
|
|
thing. And that is issue commands to the microprocessor. And all
|
|
programs when broken down to their simplest form are nothing more than
|
|
a collection of 80XXX instructions and program specific data. This is
|
|
the level of assembly language. In assembly you have total control of
|
|
the system. This is also the level that the debugger operates at.
|
|
|
|
You don't have to become a master at assembly to crack a program, but
|
|
it helps. You do need to learn some rudimentary principles, and you
|
|
absolutely have to become familiar with the registers of the cpu and
|
|
how the 8088 instruction set uses them. There is no way around this.
|
|
How proficient you are at assembly will determine how good of a cracker
|
|
you become. You can get by on learning a few basic instructions, how to
|
|
use a debugger, and one or two simple techniques. This will allow you
|
|
to remove a few shareware nag screens, and maybe you'll luck out and
|
|
remove the copy protection from a game or two, but that's it.
|
|
|
|
You can then dynamically interact with the program and run it one line
|
|
of code at a time, and see exactly what the program is doing in real
|
|
time as each line of code is executed. You will also be able to
|
|
re-assemble instructions (in memory only), edit the contents of memory
|
|
locations, manipulate the cpu's registers, and see the effects your
|
|
modifications have on the program as it's running. This is also where
|
|
all your system crashes will occur... There is a lot of trial and error
|
|
involved in cracking.
|
|
|
|
As you get better, you'll have to write programs that will implement
|
|
your patches if you decide to distribute them. The patches themselves
|
|
don't have to be written in assembly.
|
|
|
|
The sources code I included in this manual are extremely simple.
|
|
They're written in assembly because that's the only language I know how
|
|
to program in, but if you are already proficient in a higher level
|
|
language, it should be trivial for you to duplicate it's methods in
|
|
your preferred language.
|
|
|
|
Quick Introduction To Soft-Ice 3.0
|
|
|
|
Okay, okay, i already heard you : Hey exact, you've ripped the ED!SON
|
|
introduction. Yes, i've taken it ;) Why should i do something if
|
|
someone already did ? So for all of you that didn't have the chance to
|
|
have that intro, i've a little remixed it, and here it is...
|
|
|
|
Cracking a Windows program is most often more simple than a program
|
|
running in Dos. In Windows, it's hard to hide anything from anyone who
|
|
really looks for information, as long as Windows own functions are
|
|
used. The first (and often only) tool you need is Soft-Ice, a powerfull
|
|
debugger from NuMega (http://www.numega.com). Some people find it hard
|
|
to use, but i will tell you how to do efficient debugging with it.
|
|
|
|
To use Sice, you must load it before windows, to do that, just add the
|
|
"Drive:\Path\WINICE.EXE" at the end of your "AUTOEXEC.BAT". Normally,
|
|
the Sice Setup should have already done it. I advise you to make a
|
|
multi-config in that way, you can load Sice only when you need it.
|
|
|
|
Example of multi-config :
|
|
;--- Config.sys
|
|
[menu]
|
|
menuitem SICE,Load Soft-Ice Debugger Behind Windows
|
|
menuitem NORM,Normal Mode
|
|
menudefault NORM,5
|
|
[SICE]
|
|
[NORM]
|
|
[common]
|
|
DEVICE=C:\WIN96\HIMEM.SYS
|
|
DOS=HIGH
|
|
DEVICE=C:\cd\drivers\MTMCDAI.SYS /D:MTMIDE01
|
|
FILES=40
|
|
;--- EOF Config.sys
|
|
|
|
;--- Autoexec.bat
|
|
@ECHO OFF
|
|
SET BLASTER=A220 I5 D1 H5 P330 T6
|
|
SET MIDI=SYNTH:1 MAP:E
|
|
SET PATH=C:\WIN96;C:\WIN96\COMMAND;C:\DOS;D:\NC
|
|
SET TEMP=C:\TEMP
|
|
SET SOUND=C:\VIBRA16
|
|
C:\VIBRA16\DIAGNOSE /S
|
|
C:\VIBRA16\MIXERSET /P /Q
|
|
PROMPT $p$g
|
|
goto %config%
|
|
:SICE
|
|
C:\Progra~1\SoftIc~1\WINICE.EXE
|
|
goto common
|
|
:NORM
|
|
goto common
|
|
:common
|
|
;--- EOF Autoexec.bat
|
|
|
|
In the config.sys the [menu] indicates that's a multiconfig, it will
|
|
display the two menuitem and wait for the user to select. When
|
|
selected, the part of the config file refering to it is runned and
|
|
followed by the [common] one. In the autoexec.bat there's a %config%
|
|
variable set to the user'selection and is used to select witch part of
|
|
your bat you will execute.
|
|
|
|
So, udpate your system files if they need so, and reboot your machine.
|
|
If you don't understand why these config files look like this, refer to
|
|
the MS-DOS Help (Type HELP at the dos prompt).
|
|
|
|
Now that Sice is loaded into memory, press "CTRL-D" to to pop it up.
|
|
Here is a little description of the windows you can see on Sice screen
|
|
:
|
|
|
|
+----------------------+-------------------------------------------+
|
|
| CPU Registers Window | "WR" En/Disable, "R", "Alt-R" Edit. |
|
|
+----------------------+-------------------------------------------+
|
|
| FPU Registers Window | "WF" En/Disable. |
|
|
+----------------------+-------------------------------------------+
|
|
| Locals Windows | "WL" En/Disable, "Alt-L" Focus. |
|
|
+----------------------+-------------------------------------------+
|
|
| Watch Window | "WW" En/Disable, "Alt-W" Focus. |
|
|
+----------------------+-------------------------------------------+
|
|
| Data Window | "WD" En/Disable, "E", "Alt-D" to Edit. |
|
|
+----------------------+-------------------------------------------+
|
|
| Code Window | "WC" En/Disable, "A" Edit, "Alt-C" Focus. |
|
|
+----------------------+-------------------------------------------+
|
|
| Command Window | Type Commands and read output here. |
|
|
+----------------------+-------------------------------------------+
|
|
| Help Line | Get summary help on what you are typing. |
|
|
+----------------------+-------------------------------------------+
|
|
|
|
The register window contains the general purpose and flags registers of
|
|
the cpu. You will notice that the general purpose registers contain
|
|
hexadecimal values. These values are just what happened to be in there
|
|
when you brought up the debugger. You will also notice that some of the
|
|
flags are highlighted while some are not. The highlighted flags are the
|
|
ones that are SET. While the ones that are not highlighted are CLEARED.
|
|
Generally, the register are also highlighted when they change value.
|
|
From this window you will be able to manipulate the contents of the
|
|
cpu's registers. You will change the values of the registers while
|
|
debugging a program in order to change the behavior of the running
|
|
program. Say you come across a JNZ instruction (jump if not zero), that
|
|
instruction makes the decision on whether or not to make the jump based
|
|
on the state of the (Z)ero flag. You can modify the condition of the
|
|
(Z)ero flag in order to alter the flow of the programs code. By the
|
|
same token, you can modify the general purpose registers in the same
|
|
manner. Say the AX register contains 0000, and the program bases it's
|
|
actions on that value, modifying the AX register to contain a new value
|
|
will also have the effect of modifing the flow of the code. After you
|
|
become comfortable with using Sice you'll begin to appreciate just how
|
|
powerful this window is, and you'll aslo discover soon enough just how
|
|
totally it can screw your system if you fuck up.
|
|
|
|
The data window will display data as it exists in memory. From this
|
|
window you can usually display, search, edit, fill, and clear entire
|
|
ranges of memory. The two most common commands for this window are
|
|
display and edit. The search command is also useful in cracking. Sice
|
|
offers you 4 data windows, you can toggle from one to another using the
|
|
"data" command. You can also change the type of data this window is
|
|
displaying using the "format" command. You can scroll into the data
|
|
window using ALT and arrows or PgUp/PgDn keys.
|
|
|
|
The code window is the window in which you will interact with the
|
|
running program. This is the most complex window, and it is where the
|
|
bulk of debugging occurs. The layout of the window is pretty simple,
|
|
the group of 12 numbers with the colon in the middle of them to the far
|
|
left of the window is the address:offset of that line of code. Each
|
|
line of code in this window is an instruction that the program will
|
|
issue to the microprocessor, and the parameters for that instruction.
|
|
The registers that contain the address for the current instruction
|
|
waiting to be executed are the CS:EIP registers (code segment and
|
|
instruction pointer). This line is highlighted, if you havent it in the
|
|
code window use the "." command to retrieve it. You will also notice a
|
|
group of hex numbers to the right of the addresses, this group of
|
|
numbers is the hexadecimal equivalent of the mnemonic instructions. The
|
|
next group of words and numbers to the right of the hex numbers are the
|
|
mnemonic instructions themselves. You can scroll into the code window
|
|
using ALT and arrows or PgUp/PgDn keys.
|
|
|
|
For most examples, we'll only need to have the CPU Registers Window,
|
|
the Data and the code one. Disable others. I'm in 60 lines mode. So if
|
|
all windows are disabled to have the same screen as me do (comment are
|
|
preceded by a semi-colon) :
|
|
|
|
+--------------------+-------------------------------------+
|
|
| :lines 60 | ; Set 60 lines mode |
|
|
+--------------------+-------------------------------------+
|
|
| :color f a 4f 1f e | ; Set psychedelic colors (Optional) |
|
|
+--------------------+-------------------------------------+
|
|
| :wd 22 | ; Enable Data Window 22 lines long |
|
|
+--------------------+-------------------------------------+
|
|
| :wc 25 | ; Enable Code Window 25 lines long |
|
|
+--------------------+-------------------------------------+
|
|
| :wr | ; Enable Register Window |
|
|
+--------------------+-------------------------------------+
|
|
| :code on | ; Display instruction bytes |
|
|
+--------------------+-------------------------------------+
|
|
|
|
This can seems you strange to have to type all these commands each time
|
|
you'll start Sice. In fact, all these command can be done in the
|
|
winice.dat file (in your sice directory). Let'see what is in mine :
|
|
|
|
+-----------------------------------------------+--------------------------+
|
|
| ;--- Example of Winice.dat | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| ; General Variables | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| NMI=ON | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| SIWVIDRANGE=ON | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| LOWERCASE=OFF | ; Disable lowercase |
|
|
| | assembly |
|
|
+-----------------------------------------------+--------------------------+
|
|
| MOUSE=ON | ; Enable mouse |
|
|
+-----------------------------------------------+--------------------------+
|
|
| NOLEDS=OFF | ; Disable led switching |
|
|
+-----------------------------------------------+--------------------------+
|
|
| NOPAGE=OFF | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| PENTIUM=ON | ; Pentium Op-Codes |
|
|
+-----------------------------------------------+--------------------------+
|
|
| THREADP=ON | ; Following Thread |
|
|
| | Process |
|
|
+-----------------------------------------------+--------------------------+
|
|
| VERBOSE=ON | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| PHYSMB=16 | ; Exact Memory Size |
|
|
+-----------------------------------------------+--------------------------+
|
|
| SYM=256 | ; Memoy allocated to |
|
|
| | symbols |
|
|
+-----------------------------------------------+--------------------------+
|
|
| HST=16 | ; Memory allocated to |
|
|
| | history |
|
|
+-----------------------------------------------+--------------------------+
|
|
| TRA=92 | ; Memory allocated to |
|
|
| | back trace buffer |
|
|
+-----------------------------------------------+--------------------------+
|
|
| ; Startup sequence | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| INIT="lines 60;color f a 4f 1f e;wd 22;wc | |
|
|
| 22;wr;code on;x;" | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| ; Function Keys | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| F5="^G;" | ; Run (CTRL-D) |
|
|
+-----------------------------------------------+--------------------------+
|
|
| F8="^T;" | ; Step into functions |
|
|
| | (Trace) |
|
|
+-----------------------------------------------+--------------------------+
|
|
| F10="^P;" | ; Step Over functions |
|
|
| | (Procedure) |
|
|
+-----------------------------------------------+--------------------------+
|
|
| F11="^G @SS:ESP;" | ; Step out of function |
|
|
+-----------------------------------------------+--------------------------+
|
|
| ; Export Symbols | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| EXP=c:\win96\system\kernel32.dll | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| EXP=c:\win96\system\user32.dll | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| EXP=c:\win96\system\gdi32.dll | |
|
|
+-----------------------------------------------+--------------------------+
|
|
| ;--- EOF Winice.dat | |
|
|
+-----------------------------------------------+--------------------------+
|
|
|
|
Okay, i think, it speaks by itself. Just a little note for defining
|
|
function keys, all commands preceded by ^ are invisible, and all those
|
|
followed by a ; are executed (the ; indicates an ENTER). Dont forget to
|
|
load the Export Symbols !
|
|
|
|
Cracking ACDSee 32 V2.0 Beta
|
|
|
|
Loading ACDSee32.exe into Soft-Ice And Breaking At The Right Point.
|
|
Run the Symbol Loader, do "File/Open Module" or you can also click on
|
|
the first button on the left of the tool bar and browse until you can
|
|
select the file ACDSee32.exe. Now, to start debugging you must to do
|
|
"Module/Loads..." or click the "Load button" (next to the "Open" one).
|
|
Perhaps Sice poped-up, saying Break Due To Load Module, or something
|
|
like that, leave it by pressing "CTRL-D" or typing "X" followed by
|
|
"ENTER". You should disable the "Break At WinMain Option" to dont
|
|
pop-up Sice each time you load a module (the little lamp button).
|
|
|
|
OK, let's go. In ACDSee, click on "Tools/Register..." Fill up the boxes
|
|
with what you want. (I've filled them with Name:"Out Rage Pirates" and
|
|
Registration:"112233445566"). Generally programs must read the content
|
|
of the boxes with one of these functions :
|
|
|
|
+----------------+----------------------------------+
|
|
| 16-bit | 32-bit |
|
|
+----------------+----------------------------------+
|
|
| GetWindowText | GetWindowTextA, GetWindowTextW |
|
|
+----------------+----------------------------------+
|
|
| GetDlgItemText | GetDlgItemTextA, GetDlgItemTextW |
|
|
+----------------+----------------------------------+
|
|
|
|
The last letter of the 32 functions tells if the function uses one-byte
|
|
or double-byte strings. Double-byte code is RARE. So, now we gonna
|
|
enter Sice pressing CTRL-D and set breakpoints on the getting content
|
|
of edit boxes :
|
|
|
|
:bpx GetWindowText
|
|
:bpx GetWindowTexta
|
|
:bpx GetWindowTextw
|
|
:bpx GetDlgItemText
|
|
:bpx GetDlgItemTexta
|
|
:bpx GetDlgItemTextw
|
|
|
|
Oki, there's no need to set BPs (BreakPointS) 0 and 3 since we know it
|
|
is a 32-bit application, but i've put them here to be exhaustive. If
|
|
you encounter problems settings these breakpoints, make sure that the
|
|
export symbols are loaded in Soft-Ice : edit the file winice.dat and
|
|
check if the semi-colons are removed from the exp= that follows the
|
|
"Example of export symbols that can be included for chicago" near the
|
|
end of file. Generally, you only need to keep kernel32.dll, user32.dll,
|
|
gdi32.dll. If you get an error message "No LDT", make sure you dont run
|
|
any other DOS application in the background,
|
|
|
|
It's not sure that Sice will pop-up, and not all program are calling
|
|
these Windows functions.
|
|
Continue the program ("CTRL-D"), and click the OK button. It worked,
|
|
we're back to Sice ! press "CTRL-D" to continue the process, back to
|
|
Sice again ! re-re-press "CTRL-D", no more Sice pop-up. Normal, there's
|
|
only two textboxes... Click OK to get back to the registration window.
|
|
And now, let's throw an eye into Sice, CTRL-D. There's comments for the
|
|
two break points :
|
|
|
|
Break due to BPX USER32!GetDlgItemTextA (ET=4.70 seconds)
|
|
Break due to BPX USER32!GetDlgItemTextA (ET=269.77 microseconds)
|
|
|
|
It's BP 04 let's delete other BPs :
|
|
|
|
:bl ; BPs list
|
|
00) BPX USER!GetWindowText
|
|
01) BPX USER32!GetWindowTexta
|
|
02) BPX USER32!CharNextExW
|
|
03) BPX USER!GetDlgItemText
|
|
04) BPX USER32!GetDlgItemTextA
|
|
05) BPX USER32!AppendMenuW
|
|
:bc 0 1 2 3 5 ; Clear BPs #0, 1, 2, 3 and 5.
|
|
|
|
We'll do it again. Press "CTRL-D" to leave Soft-Ice, and click the OK
|
|
button. Magic, we're back in it... Let's do a little focus : where are
|
|
we, and what's the hell now ? We are at the start of the "Get Dialog
|
|
Item Text A" function, and we are going to find where it is called.
|
|
Since we know that when we do a far call to something the next logical
|
|
instruction address is stored on the stack, we gonna set a BP on that
|
|
address and execute the program until we reach it. G command will
|
|
continue the program at the current CS:EIP, and set a temporary BP to
|
|
the address indexed (@) in SS:ESP. There's a function key that
|
|
automatically do it, normally, it's F11.
|
|
|
|
:G @SS:ESP
|
|
|
|
Finding Where The Registation Code Is Checked
|
|
|
|
Ok, we are back into Sice at the instruction following the call to
|
|
DlgItemTextA. We gonna take a look on what's happenning before and
|
|
after. Use CTRL-UP and CTRL-DOWN to move into the code window. If you
|
|
dont have the code window on your screen you can make it appears by
|
|
typing WC (WC 20 will set the code windows to be 20 lines long). You
|
|
should see something like following (i've added blank lines and
|
|
comments for clarity and future explainations) :
|
|
|
|
; Get The Name Into Buffer (ESP+8)
|
|
0040367B 8D442418 LEA EAX, [ESP + 18] ; Buffer(For Name) Address
|
|
0040367F 6A1E PUSH 0000001E ; Max String Size
|
|
00403681 8BB42408010000 MOV ESI, [ESP + 00000108]
|
|
00403688 50 PUSH EAX ; Buffer Address
|
|
00403689 6A6B PUSH 0000006B ; Control ID
|
|
0040368B 8B3D94DA4900 MOV EDI,[USER32!GetDlgItemTextA]
|
|
00403691 56 PUSH ESI ; Dialog Handle
|
|
00403692 FFD7 CALL EDI ; Call GetDlgItemTextA
|
|
|
|
; Get The Registration Code Into Buffer (ESP+38)
|
|
>00403694 8D442438 LEA EAX, [ESP + 38] ; Buffer(Registration) Addy
|
|
00403698 68C8000000 PUSH 000000C8 ; Max String Size
|
|
0040369D 50 PUSH EAX ; Buffer Address
|
|
0040369E 6882000000 PUSH 00000082 ; Control ID
|
|
004036A3 56 PUSH ESI ; Dialog Handle
|
|
004036A4 FFD7 CALL EDI ; Call GetDlgItemTextA
|
|
|
|
; Registration Checking
|
|
>004036A6 8D442438 LEA EAX, [ESP + 38] ; Registration Buffer
|
|
004036AA 8D4C2418 LEA ECX, [ESP + 18] ; Name Buffer
|
|
004036AE 50 PUSH EAX ; Save Datas
|
|
004036AF 51 PUSH ECX
|
|
!004036B0 E80BF9FFFF CALL 00402FC0 ; Registration Check
|
|
004036B5 83C408 ADD ESP, 00000008 ; Free Stack
|
|
004036B8 85C0 TEST EAX, EAX
|
|
004036BA 7E6E JLE 0040372A ; EAX=0 Means Bad Reg...
|
|
|
|
; Do Something, sure... ;)
|
|
004036BC 8D442438 LEA EAX, [ESP + 38]
|
|
004036C0 8D4C2418 LEA ECX, [ESP + 18]
|
|
004036C4 50 PUSH EAX
|
|
004036C5 51 PUSH ECX
|
|
004036C6 E895FAFFFF CALL 00403160
|
|
004036CB 83C408 ADD ESP, 00000008
|
|
004036CE 833D44F0480000 CMP DWORD PTR [0048F044], 00000000
|
|
004036D5 740B JE 004036E2
|
|
004036D7 A144F04800 MOV EAX, [0048F044]
|
|
004036DC 8BC8 MOV ECX, EAX
|
|
004036DE 8B18 MOV EBX, [EAX]
|
|
004036E0 FF13 CALL DWORD PTR [EBX]
|
|
004036E2 833D40F0480000 CMP DWORD PTR [0048F040], 00000000
|
|
004036E9 740C JE 004036F7
|
|
004036EB A140F04800 MOV EAX, [0048F040]
|
|
004036F0 8BC8 MOV ECX, EAX
|
|
004036F2 8B18 MOV EBX, [EAX]
|
|
004036F4 FF5314 CALL [EBX+14]
|
|
|
|
; Close Registration Windows, And pops : "Thanks Registering"
|
|
004036F7 6A01 PUSH 00000001
|
|
004036F9 56 PUSH ESI
|
|
004036FA FF15F4DA4900 CALL [USER32!EndDialog]
|
|
00403700 6A00 PUSH 00000000
|
|
00403702 6820324000 PUSH 00403220
|
|
00403707 56 PUSH ESI
|
|
00403708 FF15F8DA4900 CALL [USER32!GetParent]
|
|
0040370E 50 PUSH EAX
|
|
0040370F 68E4000000 PUSH 000000E4
|
|
00403714 A148F04800 MOV EAX, [0048F048]
|
|
00403719 50 PUSH EAX
|
|
0040371A FF1544DB4900 CALL [USER32!DialogBoxParamA]
|
|
00403720 B801000000 MOV EAX, 00000001
|
|
00403725 E92EFFFFFF JMP 00403658
|
|
|
|
; Pops up a window saying : "Your name and registration code do not match."
|
|
0040372A 6A00 PUSH 00000000
|
|
0040372C A104F34800 MOV EAX, [0048F304]
|
|
00403731 50 PUSH EAX
|
|
00403732 68ACF34800 PUSH 0048F3AC
|
|
00403737 56 PUSH ESI
|
|
00403738 FF15E4DA4900 CALL [USER32!MessageBoxA]
|
|
0040373E 6882000000 PUSH 00000082
|
|
00403743 56 PUSH ESI
|
|
00403744 FF15F0DA4900 CALL [USER32!GetDlgItem]
|
|
0040374A 50 PUSH EAX
|
|
0040374B FF1548DB4900 CALL [USER32!SetFocus]
|
|
00403751 B801000000 MOV EAX, 00000001
|
|
00403756 E9FDFEFFFF JMP 00403658
|
|
|
|
Let's do a some analysis on what we are seeing. We are at 0157:00403694
|
|
(Your segment address may be different, it depends on what you load,
|
|
update my values with yours). The previous instruction is the call to
|
|
the GetDlgItmeTextA. Again, you can scroll in the code windows with
|
|
"CTRL-UP", "CTRL-PGUP", "CTRL-DOWN" and "CTRL-PGDOWN". You can also
|
|
make the Focus to the code window by pressing "Alt-C" and use the UP,
|
|
DOWN, PGUP, PGDOWN to scroll it.
|
|
|
|
In C, the call to the GetDlgItemTextA should look like this :
|
|
|
|
int GetWindowText (int windowhandle, char *buffer, int maxlen);
|
|
So the push eax is the buffer address, let's have a look :
|
|
|
|
:d esp+18 ; You can also use "db esp+18" for byte display
|
|
We've got it, it's our name ! We saw that in few intructions, there
|
|
will be second call to the GetDlgItemTextA, the CALL EDI at
|
|
0157:004036A4. We dont want Sice to break, so we will disable it :
|
|
|
|
:bd 4 ; Disable BP 4
|
|
After that second call, there's another one followed by a test on the
|
|
eax value... humm suspicious, is there any check inside that routine ?
|
|
That's what we gonna determine fastly. We gonna trace the code stepping
|
|
over function calls. Press P (Procedure trace) then ENTER (normally
|
|
it's F10 key). Press it several times.
|
|
|
|
After you've reached 0157:004036A6 (the second call) our registration
|
|
code appears in the data window (if it is big enought, else you can
|
|
scroll it down using Alt-DOWN) our predictions were right ;). You are
|
|
now reaching the TEST AX,AX intruction (0157:004036BA), then there's a
|
|
branch to another routine (0157:0040372A), the program will follow it
|
|
and soon you will get a message saying that your registration code is
|
|
wrong... (0157:00403738).
|
|
|
|
So now we are sure that the call before the test was done to check the
|
|
data we've enterred, and that the branch choose the direction to the
|
|
Registration Not Match message. What if we change the direction the
|
|
program took?
|
|
|
|
Let's go, enable BP 4.
|
|
|
|
:be 4 ; Enable BP 4
|
|
|
|
Leave Sice (CTRL-D), click on OK to get back to the registration
|
|
window, and click on OK again to pop-up into Sice. Press CTRL-D another
|
|
time to go to the second GetDlgItemTextA call and press F11 to go out
|
|
of that function call. Now step to the branch (F10 until you reach
|
|
0157:004036BA). And change the zero flag value to disable it:
|
|
|
|
:r fl z ; Toggle Zero Register FLag
|
|
Then leave the proggy to himself (CTRL-D). We've done it ! The
|
|
beautifull message appears : thanks for supporting our products, etc,
|
|
etc...
|
|
|
|
Hu Oh, Hey, what's that stupid program ? If i click on the little eye
|
|
(the about button in the toolbar), it's telling me it is not registered
|
|
!!!? Fucking damn thing, we gonna gotcha !
|
|
|
|
Oki, let's think two seconds... what's the matter ? Well everything
|
|
seems like if ACDSee checks the name and the registration at every
|
|
times it shows them. So, to avoid this problem, we've got to give him
|
|
the answer he wait each times he call the registration checker.
|
|
First of all, we must verify our affirmations, we must know if the
|
|
routine wich is called by the about button is effectively the piece of
|
|
code into this call. Go into Soft-Ice using the BP we've set on the
|
|
GetDlgItemTexta (go to the registration window and press enter), and
|
|
press F11. Now, we're going to put another BP into the call.
|
|
|
|
:bpx 0157:00402FC0 ; Change the address in regard to yours
|
|
Now we gonna try, leave Soft-Ice (it will pop-up two times because BP 4
|
|
is still enabled, we're not interrested into these breaks), close the
|
|
registration window by clicking cancel and finally click on the about
|
|
button... Yep! back in Sice, we were right !!! So everything we've got
|
|
to do now is to send back a satisfying answer to the calling code...
|
|
|
|
Patching ACDSee
|
|
|
|
Actually in your code window, you should have something like the
|
|
following piece of code. All we've got to do is to leave this routine
|
|
with EAX different from 0...
|
|
|
|
; Check Name Lenght
|
|
>00402FC0 56 PUSH ESI
|
|
00402FC1 8B742408 MOV ESI, [ESP + 08]
|
|
00402FC5 56 PUSH ESI
|
|
00402FC6 E835000000 CALL 00403000 ; check name length (1st)
|
|
00402FCB 83C404 ADD ESP, 00000004
|
|
!00402FCE 85C0 TEST EAX, EAX
|
|
!00402FD0 7504 JNE 00402FD6 ; branch is followed
|
|
!00402FD2 33C0 XOR EAX, EAX ; Set EAX to 0 (BAD!)
|
|
00402FD4 5E POP ESI
|
|
00402FD5 C3 RET ; Exit 1
|
|
|
|
; Check Registration Code
|
|
:00402FD6 8B44240C MOV EAX, [ESP + 0C]
|
|
:00402FDA 50 PUSH EAX
|
|
:00402FDB 56 PUSH ESI
|
|
:00402FDC 6848F34800 PUSH 0048F348 ; "-294378973"
|
|
:00402FE1 E86AE70100 CALL 00421750 ; The key is herein (2nd)
|
|
:00402FE6 83C40C ADD ESP, 0000000C
|
|
:00402FE9 83F801 CMP EAX, 00000001
|
|
:00402FEC 1BC0 SBB EAX, EAX
|
|
:00402FEE 5E POP ESI
|
|
:00402FEF 40 INC EAX
|
|
:00402FF0 C3 RET ; Exit 2
|
|
|
|
So what we gonna do is erase the three instructions that works on EAX
|
|
with our own code. Dont forget to change the address in regard to your.
|
|
Erasing the branch will assure us that only our code will be followed.
|
|
There's thousand of way to modify this code, i choosed the following :
|
|
|
|
:a 0157:00402FCE ; Assemble
|
|
0157:00402FCE mov eax,1
|
|
0157:00402FD3 nop
|
|
0157:00402FD3 ; Press escape to stop assembling
|
|
:bc 0 ; Clear BP on 0157:00402FC0
|
|
|
|
And now let's check our work ! Press CTRL-D, welldone, the thanks for
|
|
registering message appears... Okay, now click on the about button...
|
|
(suspens) !!!YES!!! we've registered it.
|
|
|
|
Oki let's do our work, now we've only got to make the patch...
|
|
What we need to know is where are these instructions in the
|
|
ACDSee32.exe file. I've use HexWorkShop for win95 and found them making
|
|
a search for 85C0750433C0 (the instructions Opcodes, if Sice doesnt
|
|
show the type "CODE ON") the one interesting us are at offset 23CE. Now
|
|
we must make a little proggy to replace these bytes with our code. Here
|
|
it is :
|
|
|
|
;--- ORP-A32B.ASM
|
|
Title Patch For ACDSee 32 2.0 Beta
|
|
.Model Huge
|
|
.386
|
|
.Stack 100h
|
|
|
|
.Code
|
|
mov ax,cs
|
|
mov ds,ax
|
|
mov es,ax
|
|
|
|
mov ax,3d02h
|
|
mov dx,offset cs:fname ; DX=*FileName
|
|
int 21h ; DOS/FileOpen
|
|
jc errorlbl ; Jump On Errors
|
|
|
|
mov word ptr [offset cs:fname],ax ; BX=Handle
|
|
mov bx,ax
|
|
|
|
mov ax,4200h
|
|
xor cx,cx ; Segment
|
|
mov dx,23ceh ; Offset
|
|
int 21h ; DOS/FileSeekSet
|
|
jc errorlbl ; Error !
|
|
|
|
mov ax,4000h
|
|
mov bx,word ptr [offset fname] ; BX=Handle
|
|
mov cx,6 ; Lenght
|
|
mov dx,offset patch ; Buffer
|
|
int 21h ; DOS/WriteFile
|
|
jc errorlbl
|
|
|
|
mov ax,3e00h
|
|
mov bx,word ptr [offset fname] ; BX=Handle
|
|
int 21h ; DOS/CloseFile
|
|
jc errorlbl
|
|
|
|
mov dx,offset cs:text2
|
|
jmp getout
|
|
|
|
errorlbl:
|
|
mov dx,offset cs:text1 ; Print
|
|
getout: mov ah,9
|
|
int 21h
|
|
|
|
mov ah,4ch ; Get Out Of Here !
|
|
int 21h
|
|
|
|
patch db 0B8H,001H,000H,000H,000H,090H ; MOV EAX,00000001 - NOP
|
|
fname db 'ACDSEE32.EXE',0
|
|
text1 db 0ah,0dh,'Error Handling File'
|
|
text2 db 0ah,0dh,'Patch By Exact /oRP',0ah,0dh,'$'
|
|
end;--- EOF ORP-A32B.ASM
|
|
|
|
You can compile it with tasm 3.1 and tlink 5.1 (they can be found on my
|
|
home page) in that manner :
|
|
|
|
TASM /m9 /n /q orp-a32b
|
|
TLINK /3 /x orp-a32b
|
|
|
|
I think there is not so much comment to add at the source, anyway if
|
|
you have any problems understanding what happening in there, you must
|
|
find a book about programming (you can also try to get Helppc).
|
|
|
|
Final Note
|
|
|
|
Ok, this is the End...
|
|
A really BIG thanks is going to ACP of UCF for sending me W32DASM !
|
|
|
|
Have Fun With This Stuff !
|
|
eXact /oRP
|
|
aka sice_boy
|
|
|