faq text.jpg (6135 bytes)

We hope that theres Faq help you.


[Q1]. When I remove the ';' from the following lines in winice.dat,






I get an error message at start-up (while SI loads (before win)) saying:

"Loading c:\windows\system\user.nms

File not found

Press any key to continue loading windows. CTRL-C to terminate"


[A1]. You are UN-commenting the 'load symbols' lines.
You want to uncomment the 'load exports' lines (EXP=... I believe) as you do not have debug symbol files [*.nms files] for Windows. or you can create *.nms files for the above using symbol loader.


[Q2]. What is the "x" in numbers (such as: 0x00045). I see this used quite often.

[A2]. C notation for hexadecimal. 0x... means 'hex'

[Q3]. What does the Symbol Loader do and when can we use it in the cracking process?

[A3]. Loads a file and breaks on the main() function (the program entry point) [though you can configure it not to]. Also can be used to dynamically load exports or symbols (i.e. EXP= stuff found in winice.dat, load it without restarting), though this can be done with nmsym.exe (old SI) as well. Use it to load a program that you need to trace from the start of the code, or to load a exports when you cant be bothered to edit winice.dat & restart.

[Q4]. "push eax - pushs eax onto the stack" they say. What does this mean? Yes I know how a stack works but isn't this just "set eax to a value"? or does this mean push the value at address eax. or what. (I have made myself even more confused by this q)

[A4]. This means push the contents of eax onto the stack. If the command says push [eax], then it means push the value at addr eax onto the stack. It has nothing to do with setting eax to anything [that would be 'pop eax']. When you see a push eax, you'll have to think that the value of eax is stored somewhere and with pop eax, the last value stored by a push is written in eax, and removed from it's storage place

for example :

mov eax, 20

push eax

mov eax, 10

pop eax

/* eax=20 now


mov eax,10

mov edx,20

push eax

push edx

mov eax,0

pop eax

/* here eax=20

pop eax

/* here eax=10

[Q5]. Just say I wanted to mov 90h to address 000044XX. how would I do it?

mov eax,90

mov 000044XX, eax


mov [000044XX],90 ??? or a better way??

[A5]. You have to go through a register, you cannot move immediate values 90h to immediate memory locations such as [000044xx]. So the 1st should work. This may be useful when you want to patch some code in memory after it has been unpacked. i.e. move a NOP (90h) to the offending instructions.

[Q6]. When I search for a string in SI, which locations indicate duplicates. I.e. what's the "good" range. Also can I have some details on this command? syntax etc?

[A6]. I think anything over 0030:0080xxxx is a duplicate. Best to leave the trailing two digits off, so that duplicates of your search are easy to recognise. i.e. just say you enter 123456789 as your serial, search for 1234567.

(For Windows 95 and Windows NT)

S [-cu][ [address] L [length] [data-list]]

address Starting address for search.

length Length in bytes.

data-list List of bytes or quoted strings separated by commas or spaces. A quoted string can be enclosed with single or double quotes.

-c Make search case-insensitive.

-u Search for Unicode string.


Memory is searched for a series of bytes or characters that matches the data-list. The search begins at the specified address and continues for the length specified. When a match is found, the memory at that address is displayed in the Data window. and the following message is displayed in the Command window.


If the Data window is not visible, it is made visible.

To search for subsequent occurrences of the data-list, use the S command with no parameters.

The search will continue from the address where the data-list was last found, until it finds

another occurrence of data-list or the length is exhausted.

The S command ignores pages that are marked not present. This makes it possible to search

large areas of address space using the flat data selector (Windows 3.1/Windows 95: 30h,

Windows NT: 10h).

Example: This example searches for the string 'Hello' followed by the bytes 12h and 34h starting at offset ES:DI+10 for a length of ECX bytes.

S es:di+10 L ecx 'Hello',12,34

This example searches the entire 4GB virtual address range for 'string'.

S 30:0 L ffffffff 'string'

[Q7]. Where can I get precise details on all assembly commands. Most of these tend to think that you want to program in assembly. I don't I just require details on commands.

[A7]. Intel instruction set reference. See their web site, under developers, or look for 'opcode ref's' on various asm/cracker sites.  Visit http://www.intel.com

[Q8]. What does REPZ do?

[A8]. REPE/REPZ - Repeat Equal / Repeat Zero

Usage: REPE


Modifies flags: None

Repeats execution of string instructions while CX != 0 and the Zero

Flag is set. CX is decremented and the Zero Flag tested after

each string operation.

[Q10]. Is sourcer better that WDASM? It is a lot bigger... What other disassemblers are there? Can u give me the url? (Official or unofficial)

[A10]. (mammon_) Sourcer is more versatile than W32Dasm; I like it better, though I have mapped it to output to MultiEdit (i.e. batch file :) which I have already set up as an awesome cracking environment Other disassemblers? IDA. Borg. Rec. PEDisasm. There are a host of others, but I cannot think of their names just yet. Most are for DOS/Z80, but Sourcer/IDA/W32Dasm are the main win ones. Borg is coming along well, too. Sites(IDA)=http://www.datarescue.com/. also search for "LORD CALIGO" as his site usually possesses such cracker tools.

[Q11]. Sometimes when I step out of some code, it leads to a dead end. (i.e. Kernel, User, User...) why is that, I mean no sign of the caller?

[A11]. You mean you see:


This usually indicates either a ring3-ring0 transition, or some other 'fault handler'...most often pages faults, interrupts, etc. The caller will still be in the stack, unless the location was JMPed to. Try typing "stack" when you break.

[Q12]. A function (IsFullVersion) is found within a dll. How can I break whenever this function is called?

[A12]. This sounds like Ulead ???? ha, ha, he, he oh my. oh yes the q... load exports for the dll (either in winice.dat EXP= or use symbol loader and load dll), then CTRL-D and type "bpx IsFullVersion". You may want to "exp IsFull*" in SI first to see if the exp load worked. You can also "bpx dllname.dll "to break on all calls to that DLL.

[Q13]. How can I convert quickly Dec to Hex? (Using SI & Manually), e.g. 1998

[A13]. (_mammon's)


1998 / 256 = 7 R 206

206 / 16 = 12 R 14

Hex# therefore is 7 12 14, or 7CE

If #/256 > 16, bump up a power of 16, to

# / 4096


Multiple 1st position by 16, multiple 2nd by 16*16, etc; add all together.

(Understand?_no?_OK i'll_explain...)


Decimal-2-Hex: (base 10 to base 16) - using Repeated Division:

We are converting from base 10-16 here, but this method will work for all base conversions (dec>base). As you know (base10 = 123456789[10]), i.e. at 10 (10th place) you turn to 2 digits. (Base16 = 123456789ABCDEF[10], i.e at 10 (16th place) you turn to 2 digits). OK, we have decimal 1998 to convert 2 hex, lets do it:

hex (b16) 0 |1 |2 |3 |4 |5 |6 |7 |8 |9 | A | B | C | D | E | F |

dec (b10) 0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |10 |11 |12 |13 |14 | 15|


n | Decimal value | base to | Answer(b10) | Remainder(b10)| Remainder(b16)


(a) 1998 / 16 = 124 r 14 E

New_Decimal_value=previous_Answer(b10) until answer=0

(b) 124 / 16 = 7 r 12 C

New_Decimal_value=previous_Answer(b10) until answer=0

(c) 7 / 16 = 0 r 7 7

Hex value is therefore 7CE (remainders read bottom up). This method works for all base conversions including into binary. _mammons_ method is also the same (as mathematicions will notice).


7CE->dec (^ indicates raised to the power of)

base from | Column (Right>left) | ValueOfCharacter (b10) | total


( 16 ^ 1(-1) ) x 14 = 14

( 16 ^ 2(-1) ) x 12 = + 192

( 16 ^ 3(-1) ) x 7 = + 1792


Decimal Value: 1998

you may be thinking, hangon: _mammon_ said:

"Multiple 1st position by 16, multiple 2nd by 16*16, etc; add all together." OK he's wrong, typing error I believe. A correction may be "Multiply 1st position by 16^0, multiply 2nd by 16^1, third by 16^2, etc; add all together". By the way in SI just type "? 7CE" to get "1998".

[Q14]. What's a nibble, word, byte etc...


Value | cap | Space |


nibble (0..15) 4 bits (1/2 byte)

byte (0..255) 8 bits (1 byte)

word (0..65535) 16 bits (2 bytes)

dword (0..4294967295) 32 bits (4 bytes)

Kb - 1024 bytes

Mb - 1024 Kb

Gb - 1024 Mb

Tb - 1024 Gb

[Q15]. When I move my mouse in SI, SI thinks I'm right clicking, and brings up the menu. I have an Intellimouse. (It worked fine when I upgraded to Win98 (with same installation)), but the program arose again on downgrading. Can I disable the mouse?

[A15]. try editing winice.dat or change the configuration through the "mouse setup" icon generated by SI. Temporarily turn your mouse off by typing "set mouse off" in SI.

[Q16]. Does Numega (Debugger & Disassembler producers) condone anti-debugging tricks? Or will they fight them?

[A16]. Of course not. These tools are intended for developers, not crackers; developers never put anti-sice code in their product until they are done, err, debugging it. See The OWL's old how-to-fix-Softice essay on fravia's. Although they may modify their debugger etc. If the trick can be an actual bug in THIER program (debugger) and their tool is fooled/crashed by it.

[Q17]. I noticed that I have "Microsoft Developer Studio" installed when I clicked "debug" on a "this program has performed and illegal operation" dialogue. It disassembled the file and presented me with the disassembly. I have not heard this tool discussed. Can we use it while cracking?

[A17]. It is intended as a source level debugger. Borland is just the same, as is Symantec, and most other commercial compiler IDEs. Some set the AeDebug key in the registry to hook these faults, others load --usually .DPMI modules-- in the system.ini. If you like it, use it; it'll be like using TDB where you cannot step into Windows system calls(e.g. getsystemtime etc).

[Q18]. What's the difference between "DWORD PTR XYZ" and "DWORD XYZ"?

[A18]. One is a pointer to a value, the other is a value. Both are size DWORD (4 bytes)

[Q19]. Self-Modifying Code: is this when the program modifies itself onto disk (secondary storage). I.e. changes itself physically or is it when it changes itself in memory?

[A19]. The last one. Usually, a program that writes to its own code segment during runtime.


[Q20]. How does the program manage to crash itself? I mean, I NOPed the nag routine, which caused it to crash. Is there any way I can pinpoint the offending instruction[s].

[A20]. Program crashing is usually not done by the program: it's done by the cracker. It means you missed something, i.e. you NOPped the wrong call, or the call returns a value that you didn't supply, or that the call has uses in addition to the nag. Beginners often think this is anti-debugger code or a special nasty protection: really it means you patched the wrong location. Try again.

[Q21]. How can I find the entry point of a windows exe using SI only?

[A21]. load it with symbol loader. it will break on main(), the entry point.

[Q22]. How can I tell SI to break when any instruction is called from a specified dll/vxd/exe etc.

[A22]. BPX modulename.

[Q23]. What is the *average* age of a "top" cracker? I mean what age should they blossom. I have seen many bibliographies on hackers, but none on crackers.

[A23]. 12-60, roughly speaking. Usually when old enough to reason but not old enough to be senile, and 'blossoming' after 1-3 years in the art. More or less.

[Q24]. Will Numega still help "us" to "make software work" in the future?

[A24]. No chance. Their tools are useful, but they do not support crackers. Although they look like a good/big company that will continue to produce such tools.

[Q25]. How can flags be set/unset.

[A25]. Use the Register command, with the FL (flags) register and the flag mnemonic. e.g.: "R FL Z" means toggle zero flag. The mnemonics are in the register window of SoftICE. (Type "wr" to toggle this)

[Q26]. Is it possible for self-modifying code to exist/work on a write-protected disk? Is it possible In any way to write to a write protected disk without permission? (OK I know its crazy).

[A26]. Yes. No, there usually is a hardware lever that prevents disk writing if the [floppy] is protected, it is not a software flag--but if you write your own floppy driver, you might be able to get away with it.

[Q27]. When a program exits (finishes execution) How can I tell?. I.e. program "exit" point.

[A27]. Nope, no such thing. You can look for the DOS 'terminate to DOS' interrupt if you like (DOS progies).

[Q28]. How can I download *all* htm files at fravia site? i.e fravia.org\*.*?? (no I'm not joking)

[A28]. Teleport Pro. Works great.

[Q29]. How to certain jumps operate? I mean "JZ XYZ" jumps if the Zero flag is set, what about others? I see JG XYZ, (I know it mean jump if greater), but Jump if what is greater???? Can somebody help me please?

[A29]. Take it all... (Use this with A34)

Jxx - Jump Instructions Table

Mnemonic Meaning Jump Condition

JA Jump if Above CF=0 and ZF=0

JAE Jump if Above or Equal CF=0

JB Jump if Below CF=1

JBE Jump if Below or Equal CF=1 or ZF=1

JC Jump if Carry CF=1

JCXZ Jump if CX Zero CX=0

JE Jump if Equal ZF=1

JG Jump if Greater (signed) ZF=0 and SF=OF

JGE Jump if Greater or Equal (signed) SF=OF

JL Jump if Less (signed) SF != OF

JLE Jump if Less or Equal (signed) ZF=1 or SF != OF

JMP Unconditional Jump unconditional

JNA Jump if Not Above CF=1 or ZF=1

JNAE Jump if Not Above or Equal CF=1

JNB Jump if Not Below CF=0

JNBE Jump if Not Below or Equal CF=0 and ZF=0

JNC Jump if Not Carry CF=0

JNE Jump if Not Equal ZF=0

JNG Jump if Not Greater (signed) ZF=1 or SF != OF

JNGE Jump if Not Greater or Equal (signed) SF != OF

JNL Jump if Not Less (signed) SF=OF

JNLE Jump if Not Less or Equal (signed) ZF=0 and SF=OF

JNO Jump if Not Overflow (signed) OF=0

JNP Jump if No Parity PF=0

JNS Jump if Not Signed (signed) SF=0

JNZ Jump if Not Zero ZF=0

JO Jump if Overflow (signed) OF=1

JP Jump if Parity PF=1

JPE Jump if Parity Even PF=1

JPO Jump if Parity Odd PF=0

JS Jump if Signed (signed) SF=1

JZ Jump if Zero ZF=1


[Q30]. ?

[A30]. !

[Q31]. When you format your hard-disk/floppy-disk, format utility makes a random serial for you. How can you change this?

[A31]. You need a utility such as Norton's DiskEdit, also allows U to change date stamp etc (You can find it with Norton's Utilities).

[Q32]. I frequently use patches/cracks, how can I quickly locate where the program/crack has made the patched.

[A32]. Copy the file2be patched to *.bak. Apply the patch. go to DOS and type "fc /b Original.bak patched.exe>c:\thecrack.txt" this will redirect the output of the changes into a file called thecrack.txt on drive c:\. Note if you want to append to an existing file, use ">>" instead of ">".

[Q33]. I'm using W32DASM. I usually see a "h" at the offset-address. What does the "h" stands for?

[A33]. The "h" simply stands for hex. (Same as 0x in C).

[Q34]. What do those abbreviations in the upper right in WinICE stand for?



C =  Carry Flag

P =  Parity Flag

A =  Auxiliary Carry Flag

Z =  Zero Flag

S = Sign Flag

I =  Interrupt Flag

D =  Direction Flag

O =  Overflow Flag

[Q35]. I've seen an A and a W at the end of some functions. What's this for?

[A35]. If a function had an A or W at the end, it's 32-Bit. Not all 32-Bit-Functions have an A or W at the end.

[Q36]. SoftICE didn't pop up when I set a Breakpoint to the functions GetDlgItemText, GetDlgItemTextA, GetWindowText, GetWindowTextA. What the hell can I do now?

[A36]. Place a breakpoint on HMEMCPY. Most times this will work if the other APIs fail. Place the breakpoint after you've typed the password! Then search for your password (s 0 l FFFFFFFF "987654321" or s ds:0 l FFFFFFFF "987654321"). You'll get the memory addresses containing your string. Place a breakpoint on memory (BPM) access to this functions. The Cxxxxxxxx and 8xxxxxxxx locations aren't important. Disable/Delete the HMEMCPY breakpoint (BD/BC).

[Q37]. What's is a "mnemonic"?

[A37]. A mnemonic is an abbreviation; e.g. CMP is the mnemonic for COMPARE. Used in LLP.

[Q38]. What breakpoint can I use for serial-catching, when there's no button to press, so that the program checks this?

[A38]. It's obviously, that this program checks it in real time, so enter your favorite registration details and then set a breakpoint to HMEMCPY. Press F12 until you get back to the program's code. Analyze the code and crack it! (I even saw a program use getwindowtexta with a timer).

[Q39]. Am I just stupid or is it impossible to get WinICE to write to a file. Say for example I want a screen of SoftICE to be written to a text file so I can examine it later. Can this be done?

[A39]. First fire symbol loader and go to SoftICE initialisation settings. Put a history buffer size more of KB, obviously :-) (default is 256, not enough for big listing). Then fire WinICE / NTICE. Put your breakpoints and all to arrive at the wanted code. Disassemble with for example, U CS:EIP L 1000

And after that CTRL-D immediately to return to W95/NT, fire again symbol loader and choose File/Save SoftICE History As ... And the saved file contains your code, WinICE loading, all you type (even if you're tracing WITHOUT code window on), etc.

[Q40]. Where can I get Trial Versions of Numega Software?

[Q40]. ftp://ftp.kgb.ru/NTUtil/NuMega and ftp://kgb.quarta.com/NTUtil/NuMega and of course http://www.numega.com (here you have to fill in some information in a form!)

[Q41]. Where can I download Cracks?

[A41]. Warez sites etc. Search for "warez MDK crack" for example, using a search engine. (What, you, a lamer? no, can't be).

[Q42]. I recently purchased M$ Pacman. It came on 3 1/2-inch floppy diskettes. When I ran the program it asked me for a name and a serial no. and tried to write back to the disk (which I obviously write protected). It would not continue without writing this. I tried to copy the floppy disk onto another one but surprisingly it contained 1.66MB of data. A normal 1.44MB disk, what's going on?

[A42]. (1.72 MB medium and 1.68MB medium) The 1.72MB media is a special format automatically recognised by Windows 95 when you use Explorer or any other Windows shell. Windows 95 cannot format 1.72MB but is able to read and write to this type of disk media. The 1.68MB media is the non-standard format used by Microsoft to distribute its software packages. This format is identified as 1.68MB or MSDMF media type. The number of sectors of the MSDMF type is equal to the 1.72MB type; the difference is that the MSDMF format only allows 16 files or directories on the disk root, while the 1.72MB, having two more tracks on the disk surface, allows a root directory equal to that of a 1.44MB diskette. Get an ordinary disk and format it to this capacity, then copy info onto it. A utility that can do such a thing ="GR Disk Utility" "http://www.bsoftware.com/cgi-bin/fetchsan.cgi?AuthorID=499,LocationID=1" or "http://mini.net/cgi-bin/sax?2347".

[Q43]. I am looking for a key logger. I have seen *many* shite ones on the net, such as keylog95, IinvisibleLogger. I mean they are so apparent that they ought to say "I am a keylogger, please give me your password so that I could write it to c:\dos\logx\keyslogged.txt". God, mighty. I want to get passwords.

[A43]. Get the tool, find what you dislike, modify it & use it. I did just that and I have an *excellent* keylogger. No task-list, No icon, no unnecessary disk usage, encrypted log, no visible process, Total VxD technology. Its called "SKI" (Stealth keyboard Interceptor). Search for it.

[Q44]. How may I rob an icon or change an icon of a compiled exe?.

[A44]. There are many utilities that will allow you to "rob" an icon of an executable. Such are: NeoSoft Icon Editor. I can't remember the URL for this utility though. "changing" an icon of a compiled exe is however more difficult and prone to errors. A utility can however do this. It is much better than the one above and can do much more. Download it from: www.impactsoft.com.

[Q45]. How are registers eax, ax, al and ah related?

[A45]. eax is a 32 bit register (a 'doubleword', or 'double') (see Q14). The lower part of (e)ax is ax, a 16 bits register (word) ax can be decomposed in it's higher and lower parts, ah and al. (that are 8 bits register)

(ah and al are of length 'bytes'- 8 bits).


here the higher part of is eax=934f and the lower part of (e)ax is ax : 93ab. These is the last 8 bits (byte) of it (remember 2 bits = 1 hex). Ah and Al are directly related to this as ah=93, al=ab. They are not independant. Modifying eax modifies al, ah, etc... and modifying al changes ax and eax. (NOTE: what you see in SoftICE (in the register window [if you dont have one type "wr"]) is actually the hex value. (NOTE2: (e) usually indicates the that it is a 16 bit register).

[Q46]. What holds the address of the next instruction to be executed?

[A46]. CS:IP

Code_Segement : Instruction_Pointer

[Q47]. How can I work out the physical memory address & what is the maximum accessable address?

[A47]. Use the registers CS:IP. Suppose CS=53C2h & IP=107Ah then:

53C20h */ Segement x 10h

+ 107Ah */ Offset


54C9Ah */ Physical address

Therefore if the contents of CS and IP were set to the highest accessible address (0FFFFFFh) then CS would contain F000h and IP would contain FFFFh (or vice versa). In other words there is more than one way of defining a physical memory address.

[Q48]. How can I tell if a flag is set or unset?

[A48]. A flag is set when it is in uppercase (Z, not z), it means the flag zero flag is on.

[Q49]. How do I stop SoftICE from breaking on faults caused by other programs?

[A49]. Type "faults off" in softICE.

[Q50]. How can I use the search command in softICE to find serials?

[A50]. You may want to search for your bogus serial in memory, because sometimes the real serial is generated close to it, or you may want to bpm on it (see next q).

if you want to search 'Your serial' in memory type

s 0 l FFFFFFFF 'Your serial' /* Try truncating off the trailing 2 digits (see q6)

The zero, the l (L) and the eight 'F' perform a full search.

[Q51]. How can I use the bpm command in softICE to find serials?

[A51]. This is a very useful command. Once you have found where your bogus serial is parked, you may want to do a "bpm SEG:OFFSET r". This will tell softICE to break whenever the program tries to (r)ead your bogus serial (obviously will cuz it has to validate it). Another use is to get to the decrypting routine of packed code. Find the command that you think is unpacked somewhere. Set a "bpm SEG:OFFSET w" on it. restart the program. BOOM! into softICE slap bang in the middle of the decryption routine where the command is (w)ritten to memory. Find an empty space and patch that address after the decryption routine ;)

[Q52]. What are "EXP"orts?

[A52]. A set of functions called by a program. Adding them to winice.dat allows you to break on functions such as kernel32!hmemcpy. To view your currently active exports type "exp" in softICE.

[Q53]. What different types of addressing are there?

[A53]. A Big "q"

(1) Register Addressing

(2) Immediate Addressing

(3) Direct Addressing

(4) *Indirect Addressing* (in discussion)

(5) *Indexed Addressing* (in discussion)

All these are methods a programmer can use to push/pop/call etc. within a certain memory address. I will discuss each in turn and explain how to go about following these methods of addressing:

(1) Register Addressing:

This is the normal type where the contents of one register are moved into another: (i.e. MOV AX,CX) which moves the contents of CX to AX.

(2) Immediate Addressing:

The data to be pushed is given after the op-code. (i.e. MOV AX,09) which will move 0009h to AX

(3) Direct Addressing:

The data from a specified address is moved to another (i.e. MOV AX, Address)

(4) Indirect Register Addressing:

This is the one that most people get stuck on. Here is an example command:



This *does not* mean move the contents of BX to AX. The brackets signal that we have to move the contents of the address pointed to by BX into AX. In other words BX points to a memory location where the suspect data lies. There may be cases where the real-serial/bogus-serial is pushed to a pointer address (i.e. [BX]). Sometimes calls can be made to specific addresses depending on the value of the pointer which is not determined until run-time.

(5) Indexed Addressing:



It is where a number, usually held in memory (IR) is used in combiantion with an existing address to determin the final address to be accessed, hence we cannot tell until runtime, what the contents of BI and DI will be and not knowing where a call (can also be used in call) actually came from. In such a case add BX & DI, dump the location (answer), and then dump the address refered to be this answer. I think you can use "D bx->di" in SI too.




How may you know when Indexed Addressing/ Indirect Addressing is being used?



000X: RET


00XX: PUSH 0057


R e f e r e n c e t o s t r i n g " f e c h o f f , S e r i a l I n c o r r e c t"


Wot? No reference of any jump? how they hell did the program get to 000Y in the first place? OH I know, It's using Indexed Addressing or Indirect Addressing. Use SI to see how the hell the program got to this section of the code. In some cases it can alter values of the stack which it can use not to go back to the call where it came from. ;(

[Q54]. I havent programmed in *any* language before. I want to crack and learn to program. I am new to computers. Can you recommend any languages that I can study to start off with before I move onto assembly? (_me_)

[A54]. You are new to computers, right? Before you start cracking/programming I recommend that you get yourself familiar with your computer and programs etc, how they run etc. You must first learn to walk before you can run. The choice of language really depends on who you talk to. Most cracker's recommend C. This is quite good as it is quite low-level oriented and is quite similar to assembly, enabling you directly communicate directly with O/S API's, in Unix, System 7, Windows 95/98/NT etc.. . You can also consider studying a procedural language such as TP/Delphi as it is simple and will give you the *feel* to program using structured design. Also try out OOP. It sets another dimension to programming!

[Q55]. When studing serial generating algorithms I usually get stuck in some unncessary parts, can you give any pitfalls to avoid/spot.

[A55]. Uppercase conversion - One approach explained...

Many times in cracking serials, you will come accross routines that convert a string (serial) to its uppercase equvalent. It is important spot such routines and not confuse them with the protection that your studying. The key is to understand the *logic* behind the assembly. After each CMP, ADD etc ask yourself why did it do that??? Look at all registers all the time. Try to *feel* the code. Believe me this approach is much better than the usuall "dump everthing pushed until U find the serial" or "search for begger off string, scroll up and inverse 1st jump" methods that have been adopted by the casual crackers/newbyes. and also be some tutorz. Try to understand the code...


[One UpperCase Routine]


Background information


ASCII table:

41h - 5Ah = A-Z

61h - 7Ah = a-z /* lower case comes after uppercase, last few things except ;)

7Ah + = {|}~ del /* useless characters

(Difference between *all* upper & lower case = 20 (i.e. 7A-5A)

Therfore hex(LowerCase) - 20 = Uppercase_Equivalent

and hex(UpperCase) + 20 = LowerCase_Equivalent



A Real Life Situation


Taken from HTMASC 2.2 ( http://www.bitenbyte.com )

This program uses the following assembly routine to convert [edx] to uppercase:



:00406219 8A02 mov al, byte ptr [edx] ; hex of byte of string to al

:0040621B 3C61 cmp al, 61 ; compare (hex) with al with "a"

:0040621D 7206 jb 00406225 ; jump if al < 61h (all UpCase characters are < "a")

:0040621F 3C7A cmp al, 7A ; compare it with "z" (7Ah)

:00406221 7702 ja 00406225 ; if greater than "z" jump (as it is not necessary to convert)

:00406223 2C20 sub al, 20 ; convert to lower case

|* Referenced by a (C)onditional Jump at Addresses:

|:0040621D(C), :00406221(C)

:00406225 8806 mov byte ptr [esi], al

:00406227 42 inc edx ; increase edx to get next char

:00406228 46 inc esi ; increase also our uppercase storage

:00406229 4B dec ebx ; decrease string length counter

:0040622A 85DB test ebx, ebx ; Will return Zero if ebx=0

:0040622C 75EB jnz 00406219 ; if not, jump back for more

[Q56]. What tricks/methods can they use when generating a serial?


* check of the name entered
- check of it's length. of the number of words (when a full name is asked, for example)
* check of the serial entered (more important here)
- length, correct chars (digits or letters, a '-' at the good place)
* manipulation of the name
- elimination of unwanted chars (ACDSee for example), change to uppercase chars
- the name is filled with chars to gain a special length

(in CS1Xedit, for example, if the name is <32 chars, the missing chars are filled with '!').

* then the calculates serial for itself.

Character Switch

First char is switched with the 11th one, etc...


Translation Tables

'A' becomes 'C', 'B' becomes 'Z', etc...

it can be used several times


The XOR trick (see next Q for full example)

The simple xor trick : if A xor B = C , then C xor B = A you can go back to A easily you just have to check what the B number is. Beware : perhaps it won't be the same all the time! 1st char xor 11, 2nd char xor 12...

The advanced XOR trick

for this one , the previous 'modified' char is used with the next char

Example :

modified_name_First_char = Original_name_first_char XOR a_certain_number

modified_name_second_char = Modified_name_first_char XOR original_name_second_char

modified_name_third_char = Modified_name_third_char XOR original_name_third_char


you get it ?

now, the problem is to reverse the algo (as usual for a keymaker)... well... you do the same thing exactly once again, but in the reverse direction. start at the end but this is not direct. Try before !

Use of size

this one is very simple for example serial = Number1 + Size * number 2 (used in GBCS softwares) or the size can be used in another way.

Use of character code

you remember ? 'A'=65, 'B'=66, etc... they can be used in many way.

[Q57]. Geek. XOR encryption? naa, too subtle for me. OK try explaining.

[A57]. Its easy...

XOR truth table



1 1 0

0 0 0

1 0 1

0 1 1

Lets encrypt the string "DreamGirl" and then decrypt it using simple XOR encryption.

DreamGirl = 44 72 65 61 6D 47 69 72 6C (hex)

(Their XOR key is.., just say 4E) Lets encrypt the text.


XOR 44,4E = <encrypted character>




0001010 > = 0A (44h -> 0Ah)



XOR 72,4E = <encrypted character>




0111100 > = 3C (3Ch -> 3Ch)


XOR 65,4E = <encrypted character>




0101011 > = 2B (65h -> 2Bh)



XOR 61,4E = <encrypted character>




0101111 > = 2F (61h -> 2Fh)



XOR 6D,4E = <encrypted character>




0100011 > = 23 (6Dh -> 23h)



XOR 47,4E = <encrypted character>




0001001 > = 09 (47h -> 09h)



XOR 69,4E = <encrypted character>




0100111 > = 27 (69h -> 27h)



XOR 72,4E = <encrypted character>




0111100 > = 3C (3Ch -> 3Ch)



XOR 6C,4E = <encrypted character>




0100010 > = 22 (6Ch -> 22h)



So my "DreamGirl" now becomes:

DreamGirl = 44 72 65 61 6D 47 69 72 6C (hex) (before encryption)

DreamGirl = 0A 3C 2B 2F 23 09 27 3C 22 (hex) (after encryption)

This may have been done by a program that is going to validate this serial number. The program has encrypted my serial so that it can compare it with a *encrypted* version of the real serial. In this case they may even hard-code the real serial (in encrypted form) into the file without qualifying for "the most stupid protection of the year" award at Fravia's dome. Note: they may use other encryption, sometimes they may not even care to get back to the unencrypted string, as they will compare the encrypted strings.

Using this XOR method it is simple to get back to the original string (hence why its called encryption):

Some_Undefined_Value = 0A 3C 2B 2F 23 09 27 3C 22 (hex) (Encrypted Crap) Our Encryption Key is "N" or 4Eh

XOR 0A,4E = <decrypted character>




1000100 > = 44 (0Ah -> 44h) = "D"



XOR 3C,4E = <decrypted character>




1110010 > = 72 (3Ch -> 72h) = "r"


XOR 2B,4E = <decrypted character>




1100101 > = 65 (2Bh -> 65h) = "e"



XOR 2F,4E = <decrypted character>




1100001 > = 61 (2Fh -> 61h) = "a"



XOR 23,4E = <decrypted character>




1101101 > = 6D (12h -> 6Dh) = "m"



XOR 09,4E = <decrypted character>




1000111 > = 47 (07h -> 47h) = "G"



XOR 27,4E = <decrypted character>




1101001 > = 69 (27h -> 69h) = "i"



XOR 3C,4E = <decrypted character>




1110010 > = 72 (3Ch -> 72h) = "r"



XOR 22,4E = <decrypted character>




1101100 > = 6C (22h -> 6Ch) = "l"


Very simply we get back to the DreamGirl.

[Q58]. I have heard that there is a hidden credits list in Windows 95. How can I access it?

[A58]. You have heard right. Here is how to get it:

Right click anywhere on the desktop and Select New | Folder.

You will have to rename this folder 3 times:

1st name it:

"and now, the moment you've all been waiting for" (and enter) then press F2 and name it:

"we proudly present for your viewing pleasure" (and enter) then press F2 again and name it:

"The Microsoft Windows 95 Product Team!" (and enter) Now double click that folder. Ta Da, (Switch yr speakers on also to hear music)

The syntax and case has to be identical! Or if you hate M$ for whatever reason and would not type that in for $1000,000,000,000 then create a new folder on your desktop with the following name: "The Microsoft Windows 95 Product Team!.{869DADA0-42A0-1069-A2E7-08002B30309D}" (copy & paste from here if you like). And double click it. Now you can write down the names of your worst enemies and pinpoint your battlez ;)

[Q59]. Can I have some precise information on the Intel 8086 Family Architecture?

[A59]. Sure:

General Purpose Registers Segment Registers

AH/AL AX (EAX) Accumulator CS Code Segment

BH/BL BX (EBX) Base DS Data Segment

CH/CL CX (ECX) Counter SS Stack Segment

DH/DL DX (EDX) Data ES Extra Segment

(FS) 386 and newer

/* (Eax) indicates 386+ 32 bit register (GS) 386 and newer

Pointer Registers Stack Registers

SI (ESI) Source Index SP (ESP) Stack Pointer

DI (EDI) Destination Index BP (EBP) Base Pointer

IP Instruction Pointer

Status Registers

FLAGS Status Flags

Special Registers (386+ only)

CR0 Control Register 0 DR0 Debug Register 0

CR2 Control Register 2 DR1 Debug Register 1

CR3 Control Register 3 DR2 Debug Register 2

DR3 Debug Register 3

TR4 Test Register 4 DR6 Debug Register 6

TR5 Test Register 5 DR7 Debug Register 7

TR6 Test Register 6

TR7 Test Register 7


Register Default Segment Valid Overrides



DI strings ES None

SI strings DS ES, SS, CS

[Q60]. How can I bypass Windows installation registration without reversing?

[A60]. Fravia+,

First, I'll start with Win95a.

Bypassing Windows registration for WINDOWS 95:

1. Copy all of the installable files (*.cab) over to the hard disk.

2. Use the EXTRACT program to extract setuppp.inf from precopy2.cab.

extract precopy2.cab setuppp.inf

3. Edit layout.inf and do a text string search for "setuppp.inf".

The line will read:


which you'll need to change to:


This tells Windows not to extract that file durring setup.

4. Edit setuppp.inf and do a text string search for ProductType= and

you'll see something that looks like:


This tells Windows that it's a full install requiring a CD key durring

setup. Change it to:


and you'll trick Windows setup into thinking it's an OEM upgrade/full

install. You'll still be asked for a registration number durring setu

but when you click on Next you'll be given the opportunity to Ignore

it and proceed.

You can do the same thing with OSR2 and any current version of Windows95. I've noticed that new burns of Win95 and Win98 have a new set of .CAB files with both setuppp.inf and layout.inf archived in precopy2.cab. Just extract both files using EXTRACT.EXE, edit them as stated above then use the ATTRIB command:

attrib +r setuppp.inf

attrib +r layout.inf

to make them read-only. This is to ensure that Windows setup won't overwrite the files. Now lets say you have a Win9X upgrade that won't let you install because it doesn't detect a previous OS installed. You can trick it into thinking that you actually have WinNT installed by doing:

dir >ntldr

on the root directory of your C: drive. This will output the dir command to a file called ntldr. If you edit the file you'll see what you should have seen if you just typed dir alone on a line by itself. Windows setup is stupid, though. It doesn't check inside the file to see if it's valid. It just checks to see if the file is there. If it is, then Windows setup will gracefully continue the install procedure, thinking you have WinNT installed... but who runs Windoze when there's Linux? ;-)

[Q61]. What does SET do in SI?


Syntax SET [ keyword] [on | off] [ value]

Use the SET command to display or change the state of internal SoftICE variables. If you specify SET with a keyword, ON or OFF enables or disables that option. If you specify SET with a keyword and value, it assigns the value to the keyword. If SET is followed by a keyword with no additional parameters, it displays the state of the keyword. Using SET without parameters displays the state of all keywords. SET supports the following keywords:

ALTSCR [on|off ]



CODE [on|off ]

EXCLUDE [on|off ]

FAULTS [on|off ]

FLASH [on|off ]

FONT [1|2|3]


I1HERE [on|off ]

I3HERE [on|off ]

LOWERCASE [on|off ]

MOUSE [on|off ] [1|2|3]


PAUSE [on|off ]

SYMBOLS [on|off ]

TABS [on|off ] [1|2|3|4|5|6|7|8]

THREADP [on|off ]

VERBOSE [on|off ]


SET CASESENSITIVE ON makes global and local symbol names case sensitive. Enter them exactly as displayed by the SYM command.

SET MOUSE ON enables mouse support and SET MOUSE OFF disables it. To adjust the speed at which the mouse moves, use one of the following: 1 (slowest speed); 2 (intermediate speed-this is the mouse default.); 3 (fastest speed).

SET SYMBOLS ON instructs the disassembler to show the symbol names in disassembled code.

SET SYMBOLS OFF instructs the disassembler to show numbers (for example, offsets and addresses). This command applies to both local and global symbol names.

Example The following example enables SoftICE fault trapping:

SET faults on

The following example sets the mouse to the fastest speed:

SET mouse 3

[Q62]. What does the command "Stack" do in SI and how can I use it in cracking?


Syntax (For Windows 3.1 and Windows 95)

STACK [ task-name | SS:[E]BP]

task-name Name of the task as displayed by the TASK command.

SS:[E]BP SS:[E]BP of a valid stack frame.

(For Windows NT)

STACK [ thread-type | stack frame]

thread-type Thread handle or thread ID.

stack frame Value that is not a thread-type is interpreted as a stack frame.


Use the STACK command to display the call stacks for DOS programs, Windows tasks, and 32-bit code. If you enter STACK with no parameters, the current SS:[E]BP is used as a base for the stack frame displayed. You can explicitly specify a stack base with a task-name or base address, and under Windows NT, with a thread identifier. If you are using STACK to display the stack of a Windows task that is not the current one, specify either its task-name or a valid SS:[E]BP stack frame. You can use the TASK command to obtain a list of running tasks. However, you should avoid using the STACK command with the current task of the TASK command's output (marked with an '*'), because the task's last known SS:[E]BP is no longer valid. The STACK command walks the stack starting at the base by traversing x86 stack frames. If an invalid stack frame or address that has been paged out is encountered during the walk, the traversal will stop. The address of the call instruction at each frame is displayed along with the name of the routine it is in, if the routine is found in the current symbol table. If the routine is not in the symbol table, the export list and module name list are searched for nearby symbols. If stack variables are present, they are displayed as well. The STACK command works in 32-bit code, however, since 32-bit symbol information support is limited to that provided in .SYM files, local variables cannot be shown. For each frame in the call stack, both the nearest symbol to the call instruction, and the actual address, are displayed. If there is no symbol available, the module name and object/section name are displayed instead. The 32-bit call stack support is not limited to applications; it will also work for VxDs and Windows NT device driver code at ring 0. Since many VxDs are written in assembly language, there may not be a valid call stack to walk from a VxD-stack base address. For Windows 3.1 and Windows 95, the call stack is not followed through thunks or ring transitions, but under Windows NT it is.

(For Windows 3.1 and Windows 95)

If you want SoftICE to pop up when a non-active task is restarted, you can use the STACK command with the task as a parameter to find the address on which to set an execution breakpoint. To do this, enter STACK followed by the task-name. The bottom line of the call stack will show an address preceded by the word 'at'. This is the address of the CALL instruction the program made to Windows that has not yet returned. You must set an execution breakpoint at the address following this call. You can also use this technique to stop at other routines higher on the call stack. This is useful when you do not want to single step through library code until execution resumes in your program's code.

Output Each entry of the call stack contains the following information:

Symbol name or module name in which the return address falls

SS:[E]BP value of this entry

Call instruction's source line number if available

Address of the first line of this routine or the name of the routine that was called to reach this routine

If stack variables are available for this entry, the following information about each is displayed:

SS:[E]BP relative offset

Stack variable name

Data in the stack variable if it is of type char, int, or long

[Q63]. Sometimes programs cause softICE to break because of a General Protection Fault. How can I pinpoint what program/module/task caused it?



Syntax TASK /*Display the Windows task list.


The TASK command displays information about all tasks that are currently running. The task that has focus is displayed with an asterisk after its name. This command is useful when a general protection fault occurs because it indicates which program caused the fault.

For Windows NT

The TASK command is process specific and only shows 16-bit tasks under Windows NT. In addition, it is only useful when the current context is that of an NTVDM process containing a WOW box. To view information or processes, refer to PROC on page 162.



Example The following example shows the TASK command on Windows 3.1 running Win32s and its output.


TaskNm SS:SP StackTop StackBot Low TaskDB hQueue Events

FREECELL 21BF:7D96 86CE0000 86D00000 10FF 121F 0000

PROGMAN 17A7:200A 0936 2070 14CE 064F 07D7 0000

CLOCK 1427:1916 02E4 1A4E 143E 144F 1437 0000

MSWORD * 29AF:913E 5956 93A4 7ADE 1F67 1F47 0000

Output For each running task, the following information displays:

Task Name Name of the task.

SS:SP Stack address of the task when it last relinquished control.

StackTop Top of stack offset.

StackBot Bottom of stack offset.

StackLow Lowest value that SP has ever had when there was a context-switch away from the task.

TaskDB Selector for the task data base segment.

hQueue Queue handle for the task. This is just the selector for the queue.

Events Number of outstanding events in the queue.

(Changes For Windows 3.1 and Windows 95)

The TASK command works for 16- and 32-bit tasks, however, the following fields change for 32-bit tasks:

StackBot Highest legal address of the stack shown as a 32-bit flat offset.

StackTop Lowest legal address of the stack shown as a 32-bit flat offset.

StackLow Field is not used.

SS:SP Contains the 16-bit selector offset address of the stack. If you examine the base address of the 16-bit selector, you see that this points at the same memory as does the flat 32-bit pointer used with the 32-bit data selector.

[Q64]. Whats this big deal on MACRO's in SI and how can I create one?


Define a new command that is a superset of SoftICE commands.

Syntax MACRO [ macro-name] | [*] | [= " macro body"]

macro-name Case-insensitive, 3-8 character name for the macro being defined, or the name of an existing macro.

macro-body Quoted string that contains a list of SoftICE commands and parameters separated by semi-colons (;).

* Delete one or all defined macros.

= Define (or redefine) a macro.


The MACRO command is used to define new Macro commands that are supersets of existing SoftICE commands. Defined macros can be executed directly from the SoftICE command line. The MACRO command is also used to list, edit, or delete individual macros. Macros are directly related to breakpoint actions, as breakpoint actions are simply macros that do not have names, and can only be executed by the SoftICE breakpoint engine. If no options are provided, a list of all defined macros will be displayed, or if a macro-name is

specified, that macro will be inserted into the command buffer so that it can be edited. When defining or redefining a macro, the following form of the macro command is used:

MACRO macro-name = " macro-body"

The macro-name parameter can be between 3 and 8 characters long, and may contain any alphanumeric character or underscore (_). If the macro name parameter specifies an existing macro, the existing macro will be redefined. The macro-name cannot be a duplicate of an existing SoftICE command. The macro-name must be followed by an equal sign "=", which must be followed by the quoted string that defines the macro-body. The macro-body parameter must be embedded between beginning and ending quotation marks ("). The macro-body is made up of a collection of existing SoftICE commands, or defined macros, separated by semi-colons. Each command may contain appropriate 'literal' parameters, or can use the form%<parameter#>, where parameter# must be between 1 and 8. When the macro is executed from the command line, any parameter references will expand into the macro-body from the parameters specified when the command was executed. If you need to embed a literal quote character (") or a percent sign (%) within the macro body precede the character with a backslash character (\). Because the backslash character is used for escape sequences, to specify a literal backslash character, use two consecutive backslashes (\\). The final command within the macro-body does not need to be terminated by a semi-colon. You can define macros in the SoftICE Loader using the same syntax described here. When you load SoftICE, each macro definition is created and available for use. SoftICE displays a message for each defined macro to remind you of it presence. Since macros consume memory, you can set the maximum number of named and unnamed macros (that is, breakpoint actions) that can be defined during a SoftICE session. The default value of 32 is also the minimum value. The maximum value is 256.

Note: A macro-body cannot be empty. It must contain one or more non-white space characters.

A macro-body can execute other macros, or define another macro, or even a breakpoint with a breakpoint action. A macro can even refer to itself, although recursion of macros is not extremely useful because there is no programmatic way to terminate the macro. Macros that use recursion execute up to the number of times that SoftICE permits (32 levels of recursion are supported), no more, and no less. Even with this limitation, macro recursion, although crude, can be useful for walking nested or linked data structures. To get a recursive macro to execute as you expect, you have to devise clever macro definitions.

Example The following is an example of using the MACRO command without parameters or options:




1shot = "bpx eip do \"bc bpindex \""

Note: The name of the macro is listed to the left, and the macro body definition to the right.

The following are more examples of basic usage of the MACRO command:

:MACRO * Delete all named macros.

:MACRO oops * Delete the macro named oops.

:MACRO xwhat Edit the macro named xwhat.

Note: Because macros can be redefined at any time, when you use the edit form of the MACRO command (MACRO macro-name) the macro definition will be placed in the edit buffer so that it can be edited. If you do not wish to modify the macro, press ESC. The existing macro will remain unchanged. If you modify the macro-body without changing the macro name, the macro will be redefined (assuming the syntax is correct!)

The following is a simple example of a macro definition:

:MACRO help = "h"

The next example uses a literal parameter within the macro-body. Its usefulness is limited to specific situations or values:

:MACRO help = "h exp"

In this example, the SoftICE H command is executed with the parameter EXP every time the macro executes. This causes the help for the SoftICE EXP command to display. This is a slightly more useful definition of the same macro:

:MACRO help= "help %1"

In this example, an optional parameter was defined to pass to the SoftICE H command. If the command is executed with no parameters, the argument to the H command is empty, and the macro performs exactly as the first definition; help for all commands is displayed. If the macro executes with 1 parameter, the parameter is passed to the H command, and the help for the command specified by parameter 1 is displayed. For execution of macros, all parameters are considered optional, and any unused parameters are ignored. The following are examples of legal macro definitions:

:MACRO qexp = "addr explorer; query %1" qexp


qexp 1 40000

:MACRO 1shot = "bpx %1 do \"bc bpindex\"" 1shot eip


1shot @esp

:MACRO ddt = "dd thread" ddt

:MACRO ddp = "dd process" ddp

:MACRO thr = "thread %1 tid" thr


thr -x

The following are examples of illegal macro definitions, with an explanation and a corrected example:

Illegal Definition: MACRO dd = "dd dataaddr"

Explanation: This is a duplication of a SoftICE command. SoftICE commands cannot be redefined.

Corrected Example: MACRO dda = "dd dataaddr"

Illegal Definition: MACRO aa = "addr %1"

Explanation: The macro command name is too short. A macro name must be between 3 and 8 characters long.

Corrected Example: MACRO aaa = "addr %1"

Illegal Definition: MACRO pbsz = ? hibyte(hiword(*(%1-8))) << 5

Explanation: The macro body must be surrounded by quote characters (").

Corrected Example: MACRO pbsz = "? hibyte(hiword(*(%1-8))) << 5"

Illegal Definition: MACRO tag = "? *(%2-4)"

Explanation: The macro body references parameter %2 without referencing parameter %1. You cannot reference parameter %n+1 without having referenced parameter %n.

Corrected Example: MACRO tag = "? *(%1-4)"

[Q65]. JosephCo's HWND method (i'll stick to tradition) is confusing. Can you explain?


I thought it wuz quite straight forward, anyway...

This method uses the BMSG command (Break on windows message) It is used to set a breakpoint on one or more Windows messages.

When a nag screen pops up, enter sice and type:


{skip the grey part 4 now}

HWND [-x][hwnd | [[ level][ process-name]] /*win95

level Windows hierarchy number. 0 is the top level, 1 is the next level and so on. The window levels represent a parent child relationship. For example, a level 1 window has a level 0 parent.

-x Display extended information about a window.

hwnd Windows handle.

process-name Name of any currently loaded process.



You should see something similar to:

Window-Handle hQueue SZ QOwner Class-Name Window-Procedure

0080 (0) 2057 32 MSGSVR32 #32711(switch_win) 17EF:00004B6E

0084 (1) 2057 32 EXPLORER shell_trayWnd 1487:0000016C...



What you want to do is scroll down the list of handles, and look at the QOWNER. Find the handle of a process that belongs to your program, and if your nag screen has an OK button, look for a BUTTON under class name. If your nag screen doesn't have one, then anything that has BUTTON after it, won't be the handle you want to break on. This is trial and error untill you get the one you want. The list of handles will probably be quite long, but usually the nag screen is amongst the first that belong to your program. Avoid tooltips (The likely suspects are the ones with # & others).

Once you think you've found your nag screen's handle, you will want to use the BMSG command. If you want to see the exact paramaters it allows, while in sice, type:


{skip the grey part 4 now}

*/ BMSG window-handle [L] [ begin-msg [ end-msg ]] [IF expression] [DO " command1;command2;..."]

window-handle HWND value returned from CreateWindow or CreateWindowEX (these are functions used to place the window onto the screen.

begin-msg Single Windows message or lower message number in a range of Windows messages. If you do not specify a range with an end-msg, only the begin-msg will cause a break.

end-msg Higher message number in a range of Windows messages.

L Logs messages to the SoftICE Command window.

IF expression Conditional expression: the expression must evaluate to TRUE (non-zero)

for the breakpoint to trigger.

DO command Breakpoint action: A series of SoftICE commands can execute when

the breakpoint triggers.

OK, now to our example. Lets assume your nag has an OK button after the handle you want to break on (easier to find), and you think you've found your proper handle. You would want to type:


Where 0084 is the handle of your nag screen. What this basically does, is tell SoftIce to break after the nag screen has been erased from the screen. You will be deep inside of some unknown API, so you will have to F12 (P RET) which stands for Pause on RETurn back your program's code. At this point you want to find where the initial nag was created (set BPX on most of the calls you come out of). The nag screen was most likely created/destroyed in same call, so if you find the proper one, do whatever you need to do. (i.e. NOP the call, inverse the jump that jumps over it, etc.)

TIP: if you don't know if you have the right handle (and you have a movable nag) type:


Then move the nag. If you have the right handle, you will break in SI, if you haven't then you won't.


BMSG xxxx WM_GETTEXT (good for passwords)

BMSG xxxx WM_COMMAND (good for OK buttons)

BMSG xxxx WM_DESTROY (good for nags)


[Q66]. I know where to break in the visual basic 3 runtime file. I hate using the CC (interrupt 3) method to get to the snippet. Is there and better/easier way that I can set a breakpoint on it?


Quite a good question. The explained can be used for any snippet if you have it infront of you like the one below.


: 8CAF 8BCA mov cx,dx

: XXXX F3A6 repz cmpsb ; <- here the strings in ds:si and es:di are being compared

: XXXX 7401 je 8CB6

: XXXX 9F lahf

: XXXX 92 xchg ax,dx

: XXXX 8D5E08 lea bx, [bp+08]

: XXXX E80E06 call 92CB

(1). BPX on hmemcpy. enter a character of your serial. You will break. PRET (F12) until you get to vbrun300.dll module. Now type bc*, and search for the hex of the snippet. 8BCAF3A674019F928D5E08, and set a bpx at the location found. BD* (to avoid unecessary breaks) , and enter all your serial, then BE* and press OK.. BOOM! your at the comparison.

(2). BPX on hmemcpy. enter a character of your serial. You will break. PRET (F12) until you get to vbrun300.dll module. Now type bc*, and set a bpx on the offset (bpx 8CAF) of where you want the program to break. BD* (to avoid unnecessary breaks) , and enter all your serial, then BE* and press OK.. BOOM! your at the comparison.

/* Using these approaches you do not need to modify the actual file. Hence better/easier!