تبلیغات :
آکوستیک ، فوم شانه تخم مرغی، صداگیر ماینر ، یونولیت
دستگاه جوجه کشی حرفه ای
فروش آنلاین لباس کودک
خرید فالوور ایرانی
خرید فالوور اینستاگرام
خرید ممبر تلگرام

[ + افزودن آگهی متنی جدید ]




صفحه 2 از 17 اولاول 12345612 ... آخرآخر
نمايش نتايج 11 به 20 از 163

نام تاپيک: آموزش کرک و قفل شکنی ( انگلیسی ) از بهترین کرکرهای روس و ...

  1. #11
    پروفشنال Morteza_SOS's Avatar
    تاريخ عضويت
    Apr 2006
    پست ها
    577

    پيش فرض

    -----------------------------------------------------
    | General CD-Check cracking revision part 1|
    -----------------------------------------------------



    Author: C_DKnight
    View with: Notepad with at least 800x600 and wordwrap turned off
    Tools used: Soft-Ice & W32Dasm (plus a Hex-Editor for patching, I use HIEW)

    NOTE that this tute assumes you POSSESS the general knowledge (use of SICE &
    W32DASM)
    of cracking. Plz go read the basics before mailing and asking me 'how do you do
    this/that?'


    Those ppl who read my first general cdcheck cracking tute know it was pretty
    lame. I wrote it when I had just begun cracking so basically I was a newbie then (still am
    tho) and didnt know a jack of shit about cracking or cdchecks

    Thats why I'm bringing you after one year (yes you read it) a revised version
    of my general cdcheck cracking guide. I know it isnt (and prolly never will be) a perfect
    tute and I also know many ppl did such tutes already but I suppose one more tute doesnt hurt
    now does it?

    I want to know what you guys & gals think about this tute, so mail me and tell
    me how to improve this (I'll try to add SafeDisc and mebbe Securom tips someday.. I
    just cant do either protection yet =/). Anyways I can be reached at [ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
    so send your questions/comments/whatever there.

    Any feedback is appreciated as long as its in the limits of readable and
    understandable form (tho all continous NAGGING and FLAMING mails will be killed!!). I will
    reply to your feedback if I think you've helped me to improve this tute or just feel you
    deserve to be mailed back Have a nice time & hope you can enjoy reading this tute, I'm
    giving my best.

    Oh.. before I forget.. DO NOT STEAL my cracks and claim they're yours!! I'm not
    involved in any game releasing/cracking also I WILL NOT RELEASE my game cracks

    If you desperately need a crack, learn to do it by yourself (this tute tries to
    help) or go and fetch a crack from somewhere on Inet. Dont mail me and ask for cracks!!
    Such mails
    will be automatically deleted

    Thx, C_DKnight



    If you feel you understood the above you can now read on where we'll begin the
    actual
    teaching/learning




    ----------------------------------------------------------------------------------------------


    ----------------
    Revision History
    ----------------

    -----------
    Version 1.0
    -----------

    - The whole crap written
    - All typ0s I could see corrected as well as some grammar hopefully improved
    - Nothing more


    ----------------------------------------------------------------------------------------------


    -----------------------------------
    | Lesson 1 - MessageBox technique |
    -----------------------------------

    The most used form of saying "Please Insert CD". I bet you have sometimes
    forgotten to insert
    the CD for the game or it is just in a wrong drive, then you have probably seen
    this message.

    These messages appear (usually) in a plain Windows Messagebox and thus are
    pretty easy to disable. The easiest method of approaching these checks is to start W32Dasm and
    search for the error message ("Please Insert CD").

    Let's have an example (all asm code is fictious throughout this tute!)

    :00450000 E80D9DFAFF call 00403000 <-- This checks for the CD
    :00450005 85C0 test eax,eax <-- Is there a CD in a drive?
    :00450007 7415 jne 00460000 <-- Jump if CD found
    :00450009 6A00 push 00450000 <-- Push parameters for msgbox

    * Possible StringData Ref from Code Obj ->"Please Insert CD"

    Disregard the push 00450000 for now as it isnt relevant.
    The important parts are the CALL followed by the testing & conditional (je &
    jne eg.) jump.

    Why?

    As described CALL 00403000 calls a part of the program that defines whether
    there is a CD in the drive or not. Then it returns the information in EAX register. Usually
    the flag for passed cdcheck is 1 and for failed 0. It is recommended to use Soft-Ice for
    tracing and finding out the correct flag values (of course this means you have to have the
    original CD!).

    That was the meaning of CALL. Now what does TEST EAX,EAX do and how does it
    work?

    Test eax,eax checks the flag in EAX which is (in this case) either 1 or 0. So
    it does a logical compare but doesnt save any values. What does that mean then? Read on and
    you'll understand.

    Then finally comes JNE 00460000, perhaps the second most important part in the
    check. This simple conditional (JMP is unconditional coz it is not affected by any register
    value) jumps depending on the CALL and the TEST. (Btw JNE stands for Jump If Not Equal).

    So if EAX=1 the JNE will jump because EAX<>0. 0 Stands for Equal when TESTing,
    so when EAX=0, it wouldnt jump, but goto the error message.


    Shortly:

    CALL checks if theres a cd in the drive and stores the result in EAX (0 or 1)
    If EAX=1 (means cd found) it will jump, taking you out to the main code.
    If EAX=0 it will not jump but goto the Error Message.


    ---------------------------
    | Lesson 2 - Ingame check |
    ---------------------------

    Easily identifiable if the game starts but suddenly nags for the missing cd eg.
    when you press "Single Player" or similar. You might get a splash (picture) that tells
    you to insert the cd so in this case we have no messageboxes (using Strn Refs to search for
    the message might get you lucky in some cases, but its rare) but we're facing an ingame
    check.

    The approach for ingame checks is a bit different, nevertheless quite easy. A
    good example of a game that uses an ingame check is Commandos : Behind Enemy Lines. But lets
    see how to deal with these checks. Firstly, where to start?

    Unless its an (old) DOS game (which we're not going to concern) there is always
    one API that practically every game use: GetDriveTypeA. It does pretty much what it
    says but for more information consult Win32 Programmer's Reference (API list).

    So if you're using Soft-Ice (which I suggest you to do!) you can type BPX
    GetDriveTypeA before you press the trigger for the CD nag ("Single Player" button eg.).
    Lets look at the asm code listing for GetDriveTypeA occurence:

    * Reference To: KERNEL32.GetDriveTypeA, Ord:0104h
    |
    :00500000 FF1508316600 Call dword ptr [0060000] <-- This calls
    the API
    :00500006 83F805 cmp eax, 00000005 <-- Is it a
    CD-ROM drive?
    :00500009 0F85CA000000 jne 0051000 <-- If not CD
    drive, jump
    :0050000F 33C0 xor eax, eax <-- Zero EAX
    (becomes 0)

    Disregard the first CALL.. its irrelevant again, you only need to know that its
    the caller
    that calls the GetDriveTypeA function.

    GetDriveTypeA -like many other APIs- store the value obtained beneath the CALL
    in EAX. Here
    is the list of the return values for GetDriveTypeA: (Taken from MisterE's fine
    tutorial )

    Value Meaning
    0 The drive type cannot be determined.
    1 The root directory does not exist.
    2 The drive can be removed from the drive.
    3 The disk cannot be removed from the drive.
    4 The drive is a remote (network) drive.
    5 The drive is a CD-ROM drive.
    6 The drive is a RAM disk.

    Value 2 is for disk drives, 3 is (obviously) Harddrives and finally 5 is the
    one you'll be
    looking for.

    If you dont already now know how the second line of the ASM code (cmp eax,
    00000005) works,
    here's a brief explanation:

    GetDriveTypeA usually starts from HD drive letters (C. Depending on how many
    drives you have
    it will be called as many times as you have drive letters -> C: then D:, E:, F:
    .. of which each
    will do cmp eax,05 (remember 5 is for CD!). So when GetDriveTypeA finally
    reaches a CD
    drive it wont jump anymore but fall on the next line of ASM (XOR EAX,EAX)...

    But this is not the whole check (mebbe in rare cases)!!
    This is only a way to determine you do have a CD drive.. the actual check is
    usually a bit
    below, like in this case (just think the above code listing is before this
    one):

    :00500011 E88D000000 call 00510000 <-- Check for
    the correct CD
    :00500016 85C0 test eax, eax <-- Still
    remember this?
    :00500018 7571 je 005ACC9F <-- Jump if
    not correct CD
    :0050001A B801000000 mov eax, 00000001 <-- Set a flag
    for passed chk

    A simple example. CALL checks for the correct CD and again stores the return
    value in EAX where
    1 is for passed check and 0 for failed. If there is a wrong CD the program will
    jump away
    to the error message most likely, but if CD is in fact the correct one a passed
    flag is set
    and the program flows on.

  2. #12
    پروفشنال Morteza_SOS's Avatar
    تاريخ عضويت
    Apr 2006
    پست ها
    577

    پيش فرض

    کرک انواع بازی به زودی .....

  3. #13
    پروفشنال Morteza_SOS's Avatar
    تاريخ عضويت
    Apr 2006
    پست ها
    577

    پيش فرض

    Micro$oft bashing
    ~~~~~~~~~~~~~~~~~

    The cracking of "Age of Empires"
    ================================
    (a general digression about CD-based copy
    protections of most Windows95 games)
    by TWD


    Hi back again,

    it's going to be Christmas and the whole world is going to shop.
    Advertising is legalized lying, said someone.
    Remember this, especially every time it's Christmas.

    Examining a game from big brother Micro$oft (of course we have
    bought it: part NO: X03-44492 :-) we have noticed a bug that may
    annoy all the poor boys (and girls) all over the (poor) world,
    whose's (poor) father and mothers, for instance, have lost their
    (poor) jobs thanks to Micro$oft's (poor) society.
    See: this reversing is a present for those who won't get no
    presents at all during these merry (poor) holidays, poor chaps,
    yet would need so much to evaluate (fully) this interesting
    (if overbloated) historical game... so let's crack it!

    And anyway I need my own cd-drive free from my own bought CD-games
    in order to hear my own music CD... something against this? :-)

    Age of Empires comes on one CD-ROM; the CD-ROM can be taken
    out after the game is running.
    I think that this tells us, that there is only one check for the CD at
    the beginning, when Age of Empires starts.
    --------------------------------------------------------------------------------
    Little (important) digression
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Let's say something general about copy protections of Windows95 games.
    They are nearly all the same, and they aren't really copy protections.
    They all work something like this :

    (1) put "c:\" in a variable, let's say "xrom"
    (2) test if "xrom" is the CD-Drive, by using "GetDriveTypeA"
    (3) if result = 5 then continue at step 5
    (4) else increment the drive letter and go back to (2)
    (5) use the letter in "xrom" to complete all path names.
    (6) if it will never find a CD-Drive, a error message appears


    A lot of games are doing it like this.
    How to crack this ??? Nothing easier like this. Don't put "c:\" in the
    variable, but the desired CD-drive letter. Then remove the
    "GetDriveTypeA" call and write something like "mov eax, 00000005".
    Sometimes a "GetVolumeInformationA" follows, but it's no problem
    to avoid the program to exit by this.

    Example games for this kind of protection :

    - Beasts and Bumpkins
    - Descent ][
    - Diablo
    - Panzer General IIID
    - and many more


    End of digression
    ~~~~~~~~~~~~~~~~~
    --------------------------------------------------------------------------------
    On the "Most stupid protections" +HCU's project is said that the
    more commercial a product is, the more stupid it's protection
    will be.
    This is sure confirmed if you take a look at "Age of Empires".

    The path to the CD is stored in the registry and only needed to find
    the oversized AVI philez.

    Set a breakpoint on "GetDriveTypeA" and start "Age of Empires".
    SoftIce pops up a few times in the "LinkInfo" module, nut this is not
    interesting.
    Sometime later, SoftIce pops up in the "Empire" module at
    this position:



    :004D65F5 57 push edi <-- the CD path
    :004D65F6 FF1554267000 Call KERNEL32.GetDriveTypeA <-- SoftIce pops up here
    :004D65FC 83F805 cmp eax, 00000005 <-- Is it the CD-ROM ???
    :004D65FF 7404 je 004D6605 <-- Yes ? --> jump !
    :004D6601 33C0 xor eax, eax <-- No ? --> stay !
    :004D6603 EB53 jmp 004D6658


    In edi is the pointer to the CD path. The result of GetDriveTypeA
    is "00000005" if the checked drive is a CD drive. If the given drive
    is a CD drive, the program continues below :

    ...

    :004D662B 57 push edi <-- the CD path
    :004D662C FF1558267000 Call KERNEL32.GetVolumeInformationA
    :004D6632 85C0 test eax, eax
    :004D6634 B800000000 mov eax, 00000000
    :004D6639 741D je 004D6658
    :004D663B 8B460C mov eax, dword ptr [esi+0C]
    :004D663E 8D4C241C lea ecx, dword ptr [esp+1C]
    :004D6642 05FD020000 add eax, 000002FD
    :004D6647 50 push eax
    :004D6648 51 push ecx
    :004D6649 E802D60500 call 00533C50 <-- strcmpi
    :004D664E 83C408 add esp, 00000008
    :004D6651 83F801 cmp eax, 00000001
    :004D6654 1BC0 sbb eax, eax
    :004D6656 F7D8 neg eax


    As you can see, not only the type of drive is checked, but also the name
    of the drive.
    In ecx is the pointer to the name of the CD currently in your CD-ROM, in
    eax is the pointer to the expected name : "AOE"

    If the compare succeeded, the result of the complete function is "01",
    else it is zero.


    To patch "Age of Empires", this function has to return "01" every time
    it is called. No problem for us, of course: let's look at the top of
    the function :

    :004D6550 81EC0C020000 sub esp, 0000020C
    :004D6556 53 push ebx
    :004D6557 56 push esi
    :004D6558 8B410C mov eax, dword ptr [ecx+0C]
    :004D655B 57 push edi
    :004D655C 55 push ebp
    :004D655D 8BF1 mov esi, ecx
    :004D655F 8B8808040000 mov ecx, dword ptr [eax+00000408]
    :004D6565 85C9 test ecx, ecx
    :004D6567 750A jne 004D6573 <--blast this one
    :004D6569 B801000000 mov eax, 00000001
    :004D656E E9E5000000 jmp 004D6658 <--jump to the end

    As we can see from the small piece of code above, the only thing which
    is to do, is to blast the jne at 004d6567. If this is done, the function
    will always return "eax = 01".

    After I nopped out some bytes (in my essay about W32Dasm 8.7) I was mildly
    criticized by fravia+, now I learned and I prefer to use this sequence :

    41 inc ecx
    49 dec ecx

    This one is doing nothing as good as two nops would do, but it can not
    be detected by some protection algorithms.

  4. #14
    پروفشنال Morteza_SOS's Avatar
    تاريخ عضويت
    Apr 2006
    پست ها
    577

    پيش فرض

    Microsoft Age of Empires I


    Tools you need: For tools you need W32DASM and a Hex-Editor. My recommendation on a Hex-Editor is Hacker's View. If you can't get these tools yourself, ask for it in a Cracker-Channel..

    Warning: You can't use WinIce and place a breakpoint on GetDriveTypeA - your computer will crash! This time you'll have to use W32DASM.


    Age of Empires is a game like some others. You can install it complete, but you can't run it without the CD inserted in your CD-ROM-Drive. Windows-Games with CD-Checks are normally easy to crack - if you know what calls CD Checks. After you've read my "Cracker's Notes" you should be able to remove CD-Checks from Windows-Games, because in Windows it's easy to do that :-).

    Step 1
    Install the full version of Age of Empires and run the game. Have you seen the error message, that you haven't inserted your CD in the CD-ROM-drive? Ok. Exit Age of Empires and QuickView EMPIRES.EXE. Look at the imports:

    Have you seen this GetDriveType?? Very interesting :-). Ok now let's go!


    Step 2
    Disassemble EMPIRES.EXE and look at it's imports. Scroll down until you see KERNEL32.GetDriveTypeA. Double click on it. Now have a look at the code:
    * Reference To: KERNEL32.GetDriveTypeA, Ord:00DEh
    |
    :004D65F6 FF1554267000 Call dword ptr [00702654]
    :004D65FC 83F805 cmp eax, 00000005
    :004D65FF 7404 je 004D6605
    :004D6601 33C0 xor eax, eax
    :004D6603 EB53 jmp 004D6658

    Look at :004D65FC. Have you seen those CMP? It compares EAX to 5. Because you've read "Cracker's Notes" you know, that GetDriveType returns values. In other words: This is the check. 5 is the value for the CD-ROM-Drive, so this line checks it.
    Now you know where the protection is and you should also know how to remove it. You can "NOP" out those 83F8057404!
    Games have not always such an easy protection. They can check several times - but then you can use nearly the same method.


    Step 3
    Copy the EMPIRES.EXE to EMPIRES.OLD! And then let's go!
    Now you know how to remove the protection, let's go! Crack this silly protection! Press F7, type 83F8057404 and replace it with 90909090909090. Now you see, that you've changed

    CMP EAX, 00000005
    JE 004D6605

    to

    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP

    There are other ways to circumvent the CD-Check. But I always tried to keep this tutorial as simple as possible, so that every Newbie can see how easy it is to remove a CD-Check from a game.


    Step 4
    Compare the EMPIRES.OLD with the EMPIRES.EXE with FC and save the differences to a file called PATCH.TXT (FC /B EMPIRES.OLD EMPIRES.EXE > PATCH.TXT). Now edit your patcher-file, compile it. Ren EMPIRES.EXE to EMPIRES.CRK and EMPIRES.OLD to EMPIRES.EXE. Run your patch. Compare EMPIRES.EXE to EMPIRES.CRK and repeat those steps until there were no differences. Enjoy the *NOP'd* Game.

  5. #15
    پروفشنال Morteza_SOS's Avatar
    تاريخ عضويت
    Apr 2006
    پست ها
    577

    پيش فرض

    Age of Empires - Rise of Rome Data Disk
    Program Name: Age of Empires - Rise of Rome
    Program Author: Microsoft
    Essay Author: SiG

    Introduction:

    I recently read The Sandman's latest essay (72) and found it very interesting indeed. I straight away went searching through all my cds looking for my Age of Empires - Rise of Rome cd which I'd bought not that long ago.On running the cd I found that it required you to have the original Age of Empires cd so I simply discarded it. Yet after reading The Sandman's essay on Magic Carpet I immediately started work on it and found it very similar yet I believe just a little bit more difficult than the Magic Carpet Crack. You will find that if you try to install Rise of Rome without having Age of Empires already present on your hard drive you will get a message telling you that AOE cannot be found. During this essay you will be shown that the Rise of Rome addon is infact a full game by itself and does not actually require you to have already purchased AOE, it's just a ploy by Microsoft to get you to by the original. It would be a good idea to have read The Sandman's essay (72) on cd protections similar to this so that you have a bit of a clearer background of the topic at hand.

    The Essay:

    Unlike with Magic Carpet running Filemon straight off won't reveal anything interesting that we can use but it will come in handy later. Instead load up the Rise of Rome installation exe, now open Regmon, click on install in the Rise of Rome exe. Switch back to Regmon and save the text to a file. Close Regmon and open the file you just saved to, for viewing. There are a lot of queries to keys that really mean nothing to us so instead search for 'age' and it should be found at a location that looks something similar to this:
    1388 Ebuf250 OpenKey HKLM\Software\Microsoft\Games\Age of Empires\1.00
    NOTFOUND


    We can see here that the Rise of Rome exe has looked for a registry key HKLM\Software\Microsoft\Games\Age of Empires\1.00 which would have been created by AOE but doesn't exist on our systems so let's make it happen. Inside HK_LOCAL_MACHINE open the key 'Microsoft' then make a new key called 'Games', inside that make a key called 'Age of Empires' and finally inside that a key called '1.00'. When finished open up Regmon once again as well as the Rise of Rome installer and do as you did before, save the text from Regmon and open for viewing. You will notice that things have changed. 1389 Ebu83b2 OpenKey HKLM\Software\Microsoft\Games\Age of Empires\1.00
    SUCCESS hKey: 0xC49AB810
    1390 Ebu83b2 QueryValueEx HKLM\Software\Microsoft\Games\Age of Empires\1.00\Launched
    NOTFOUND


    From this we can derive that the Rise of Rome exe has been satisfied with our entered registry keys, it was a success therefore it has moved onto looking for a string contained in this key called 'Launched, well no points for anyone who guesses what we have to do. Create a string in the HKLM\Software\Microsoft\Games\Age of Empires\1.00 key called 'Launched', right click on it and choose modify, type in anything just as long as the string isn't empty. Repeat the process of running Regmon on Rise of Rome and open the text for viewing. It should look similar to this:
    1389 Ebu83b2 OpenKey HKLM\Software\Microsoft\Games\Age of Empires\1.00
    SUCCESS hKey: 0xC49AB810
    1390 Ebu83b2 QueryValueEx HKLM\Software\Microsoft\Games\Age of Empires\1.00\Launched
    SUCCESS 36 35 36 35 65 62 68 6A ...
    1391 Ebu1044 CloseKey HKLM\Software\Microsoft\Games\Age of Empires\1.00
    SUCCESS
    1392 Ebu1044 OpenKey HKLM\Software\Microsoft\Games\Age of Empires\1.00
    SUCCESS hKey: 0xC49AB810
    1393 Ebu1044 QueryValueEx HKLM\Software\Microsoft\Games\Age of Empires\1.00\InstallationDirectory
    NOTFOUND
    1394 Ebu1044 CloseKey HKLM\Software\Microsoft\Games\Age of Empires\1.00
    SUCCESS


    Hmmm, well now it's looking for a string called 'InstallationDirectory', strange. Ohh well go ahead create the string yet when you go to modify it don't just type in anything. Remember back to that error message, it said something about AOE might have been moved, what this string tells Rise of Rome is where to find AOE so let's modify it so it reads c:\aoe, it could be any folder it doesn't matter, make that folder on your hard drive. Now my bet is that now Rise of Rome thinks it knows where AOE is it's going to look for a file in that directory so load up Filemon and run Rise of Rome, click 'install' and read the saved text. You will notice a new line that has appeared:

    100 12:59:48 PM Ebub231 Attributes C:\AOE\EMPIRES.EXE NOTFOUND

    Let's make a file in your c:\aoe directory which is names 'Empires.exe', edit it so that it contains any text just as long as it's not empty. Run the Rise of Rome installer and ohh my goodness you are allowed to install the game without even having Age of Empires already installed. How cool is that?

  6. #16
    پروفشنال Morteza_SOS's Avatar
    تاريخ عضويت
    Apr 2006
    پست ها
    577

    پيش فرض

    CD-COPS DeProtection

    Commercial ready-made copy protections are always interesting. Here is another one, used to protect CD-Roms. It's a nice one, timers making sure the program will crash if something takes more time than it should (as if someone would put a breakpoint somewhere and fool around), a couple of checksums to make sure no one's been changing anything in the code, and - of course - some self-modifying code decrypting itself just when it needs to be used. It even claims to be able to separate perfect CD copies from the original CD!


    --------------------------------------------------------------------------------

    CD-Cops
    Another ready-made protection annihilated
    Written by McLallo


    Introduction

    "The CD-Cops software which recognizes and either accepts or rejects the CD is protected
    by Link's Code Security, a system which has been in use since 1984 and is known throughout
    the world as being virtually unbreakable. Link's Code Security is a legend in the Middle
    East where piracy is a serious problem."
    / Quote from the CD-Cops homepage,
    کد:
    برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


    Tools required

    WDasm32 8.93
    Borland's Turbo Debugger 5.0 (Yep!)
    HEdit 2.1.11 (Or any other hexeditor)

    Hey! No SoftIce? Sorry guys, not this time.

    Target's URL/FTP

    کد:
    برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
    -- the creators of CD-Cop's.

    You won't be able to download any test versions here, I'm sorry. (They're friendly enough to offer you to buy one for only $60, though) And the application I'm using is 6 CDs, so I doubt you'll find it on the net. (But you never know what those crasy wankers out there are trading today!)

    Program History

    There are a couple of different versions of this protection:

    CD-Cops, Single version 16 bit
    CD-Cops, Single version 32 bit (this one is our target, in version 1.46)
    CD-Cops, Network version
    DVD-Cops, Single version 16 bit
    DVD-Cops, Single version 32 bit
    DVD-Cops, Single version 16 and 32 bit

    Essay

    PREFACE

    I found this CD protection on a program called Nationalencyklopedin (swedish for
    'The National Encyclopedia'). The essay will only cover how to remove the CD-Cops
    protection envelope, and not how to crack the entire application, as there is an
    extra bonus protection in the original exe-file as well, just in case. However,
    that one isn't interesting to us, and will be mentioned no more.
    --------------------------------------------------------------------------------
    START: WHAT'VE WE GOT?
    For a start, let's look what we got to play with. There are 4 files that concern us:

    NE.EXE 98 kB 16 bit application
    NE.QZ_ 63 kB Renamed 32 bit application
    NE.W_X 730 kB Renamed 32 bit application
    CDCOPS.DLL 22 kB A .dll for the protection

    Those renamed applications seem fun. I tried to rename and run them, but they both
    crashed. Hardly suprising, but you'll never know!

    Ok, so start up NE.exe and look what's it all about. First time run, it wants a code.
    If you give it a false code, a MessageBox will pop up explaining your mistake to you.

    So, to begin I went into SoftIce and put a breakpoint at MessageBox, to catch that
    'Bad code!' message. Went back to the OS and run. Bam! The whole system goes down.
    Restart the computer and throw SoftIce away. It just wont work with this protection.
    Rather than adjusting the target for the tool, I chose to pick another tool,
    Borland's good old Turbo Debugger. But first, let's try WDasm.

    --------------------------------------------------------------------------------

    DISASSEMBLING NE.EXE

    Looking around in the disassembled code for a while, I stubled into calls to encrypted
    code. Whatever you do, follow the code from the start, or just looking around, you
    won't miss them. Guess there's no use looking for that 'Bad code!' message. If there
    is sections of encrypted code, any interesting parts most certain will be in there.

    So, I followed the program flow from start to the encrypted section, and this is how
    it begins:

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:0001.0D3E(C)
    |
    :0001.0DCC 9AFFFF4F00 call CDCOPS.Ord{0003h}
    :0001.0DD1 D8A3BA70 fsub dword ptr [bp+di+70BA]
    :0001.0DD5 FA cli
    :0001.0DD6 E9F3B3 jmp C1CC

    First a call to our CDCOPS.dll, and then a large block of encrypted code! My (correct)
    guess was that the CDCops call will decrypt the code underneath, and then execute it as
    it returns. Ok, how do I decrypt it? Just setting a breakpoint at 1.0dd1, or somewhere
    else in the encrypted area, and look what's beeing runned wont do. Turbo Debugger's
    breakpoints change the code where they're put, so a breakpoint in the encrypted area
    would alter the decrypted data. Keep this problem in mind, as we'll see more of this
    in this protection.

    Decrypting the block

    What I did was to run the whole program, without any breakpoints, and when it's
    all finished, the encrypted code is still there, lying waiting for somebody to
    steal it.

    Fine! Let's save this decrypted block then! We know where it starts, but how big
    is it? I actually don't really know how the size of these blocks are determined,
    but it's really easy to see where they start and where they end in the disassembly.

    Correcting overwritten calls

    But the first time I was tricked, and the program wouldn't run at all after I had
    pasted my code over the encrypted. After a closer look I found out that the last bytes
    of the decrypted area were writing over a library call to CDCops.dll. This made the
    reallocations all screwed up. So we got to fill in this call ourselves. Actually, we
    only have to fill in the first byte, as the rest of the instruction can't be encrypted.
    because the OS needs it intact when it tries to reallocate it.

    This is how the decrypted section looks in memory, after complete run:

    :0001.1C90 2E803E9D1CC3 cmp byte ptr cs:[1C9D], C3
    :0001.1C96 75F8 jne 1C90
    :0001.1C98 90 nop
    :0001.1C99 90 nop
    :0001.1C9A 90 nop
    :0001.1C9B 90 nop
    :0001.1C9C 90 nop
    :0001.1C9D C3 ret

    Here's how my corrected version looks like:

    :0001.1C90 2E803E9D1CC3 cmp byte ptr cs:[1C9D], C3
    :0001.1C96 75F8 jne 1C90
    :0001.1C98 9AFFFF0000 call CDCOPS.Ord{0005h} // Here, 9A is the missing byte
    :0001.1C9D C3 ret

    What more have we got to keep in mind? The call att 1.0dcc to CDCOPS.3 is NOPed by
    itself while it's decrypting the block, but we can't do that, as the OS will try to
    reallocate this call as well. We'll have to leave it alone, but then we've got to
    make sure it isn't called, as it then would try to decrypt the already decrypted
    data and destory it.

    Save down the decrypted code

    Just one more thing before we can get to work; saving memory is a bit tricky in Turbo
    Debugger. I don't know if I've misunderstood something fataly, or if the Save Block
    feature just didn't work, but the only way I managed to save memory was by first to
    create a file filled with zeros, then in Turbo Debugger choose View->File... and paste
    my copied blocks there. Now, this is how I did:

    1. Create a file filled with zeros to paste the block in, at least 0xec6 bytes
    2. Load the application in Turbo Debugger
    3. Make sure there are no breakpoints (Breakpoints->Delete All)
    4. Run the program, and wait for it to finish
    5. Mark and copy from cs:0dd1 to cs:1c97
    6. View->File... and choose the file you've prepared
    7. Paste, and close the window

    Now exit and paste the saved file into NE.exe at offset 0x0fb1. Then fill in the
    missing byte (0x9a) at 0x1e78. To patch away that call to CDCOPS.3 in the beginning,
    it's time to switch over to WDasm and check for all references to 1.0dcc. Just
    one this time: 1.0d3e.

    :0001.0D3E 0F848A00 je 0DCC

    I patched this one to jump 5 bytes further. That makes 0F848F00. A 0x8f at offset
    0xf20, then.

    Now it's time to check if we made it.

    Did we?

    No, we did not. It died somewhere inside CDCops.dll. Ok, maybe that last CDCOPS call
    wasn't ment to be run after all. Perhaps it was some kind of ending routine for the
    CDCOPS.3 call? That part only seems to make sure that the decrypted code is not only
    in some cache, and as we're not modifying code while running any longer, it may not
    be needed at all. It WAS nopped when we found it, so I guess it's ok for us just to
    kill it, without really asking it's name. I changed at 0x1e70 to 0xc3 (ret). Tried
    again, and this time it runs smooth!

    First encrypted section done

    Ok, so any interesting parts in the new area? Of course there are, or they wouldn't
    have been encrypted!

    :0001.0E7C call 1067 // This one checks the registry for a code,
    :0001.0E7F jnb 0E98 // and if the code is good, jump to 1.e98!
    :0001.0E81 mov byte ptr [0DA1], 59
    :0001.0E86 push word ptr [344E]
    :0001.0E8A push 0001
    :0001.0E8C call far word ptr [0742] // This is a call to USER.ShowWindow()
    :0001.0E90 mov word ptr [0032], 06B5
    :0001.0E96 jmp 0EFE // Else if bad or no code at all, jump to 1.efe.
    // 1.efe eventually does a 'jmp word ptr [0032]'
    // so this is actually a jmp 1.6b5.

    :0001.0E98 push word ptr [344E]
    :0001.0E9C push 0002
    :0001.0E9E call far word ptr [0742] // call User.ShowWindow()
    :0001.0EA2 mov word ptr [0032], 094B
    :0001.0EA8 push word ptr [35CE]
    :0001.0EAC call far word ptr [0726] // call User.SetCursor()
    :0001.0EB0 call far word ptr [0772] // call KRNL386.Yield()
    :0001.0EB4 call 10E7 // Let's check this one out! Probably sets [35cd]
    :0001.0EB7 push word ptr [35D0]
    :0001.0EBB call far word ptr [0726] // call User.SetCursor()

    :0001.0EBF cmp byte ptr [35CD], 59 // ('Y')
    :0001.0EC4 je 1C9E
    :0001.0EC8 cmp byte ptr [35CD], 52 // ('R') If [35cd] is Y or R, then 1.1c9e
    :0001.0ECD je 1C9E
    :0001.0ED1 cmp byte ptr [35CD], 44 // ('D') If [35cd] is D, then 1.83e
    :0001.0ED6 je 0EDA
    :0001.0ED8 jmp 0EE0
    :0001.0EDA mov word ptr [0032], 083E
    :0001.0EE0 cmp byte ptr [35CD], 56 // ('V') If [35cd] is V, then 1.7ce
    :0001.0EE5 je 0EE9
    :0001.0EE7 jmp 0EEF
    :0001.0EE9 mov word ptr [0032], 07CE
    :0001.0EEF cmp byte ptr [35CD], 4E // ('N') If [35cd] is N, then 1.735
    :0001.0EF4 je 0EF8
    :0001.0EF6 jmp 0EFE
    :0001.0EF8 mov word ptr [0032], 0735
    :0001.0EFE

    Here we've got a call to the routine that checks the code, and we got some kind of
    main selector, choosing what to do. I started looking what these different letters
    in [35cd] ment:

    N (1.735) has a string reference to "Code: ". Boring, I don't wanna enter codes.
    V (1.7ce) has a reference to "Insert the correct CD". Don't wanna do that either.
    D (1.83e) refers to " ". I tried this one, it's some kind of demonstaion mode.
    Y/R (1.1c9e) is directing us to a new call CDCops.3! Definitely the best alternative.

    Second encrypted section

    Ok, so this new section starts at 1.1c9e (or 1.1ca3, if we exclude the CDCops-call),
    and scrolling down. It wasn't that obvious this time, there's a new encrypted block
    starting precisely after ours, but it looks like our last byte at is 1.1fd1.

    If we just run the program, we will never come to this 1.1c9e call. We've got to
    give it some help. So I started it in Turbo Debugger, went to 1.e7f (good code
    code entered?) and forced it to always jump, and then at 1.ec4 (jump to encrypted
    section) I forced that one to always jump too. Now, let's just run the program. It
    will most certain crash, as the code probably is used some way, and perhaps some
    other initializing is skipped with those jumps, but that doesn't destrub me. I just
    want that section decrypted. And remember to turn faults off in SoftIce, if you're
    running it, or SoftIce will pop in and your computer will crash.

    So I did like last time, and merged the new decrypted code into ne.exe. Just for fun
    I filled in the missing byte in the call to CDCops.5 (0x21ac = 0x9a), and then I put
    that ending routine out of action by a RET at 1.1fc4. Now we have to alter all the
    references to make them skip the introducing CDCops.3 call. There are two references,
    1.ec4 and 1.ecd correct them by make them jump 5 bytes further, and we're done!

    Second encrypted section done -- back to WDasm

    Ah, here's interesting stuff! It opens "NE.QZ_", reads until if finds offset 0xc544,
    where it reads 80 bytes. And this is what's happening next:

    :0001.1DC2 mov cx, 0040 // 40 words to do (80 bytes)
    :0001.1DC5 xor dx, dx
    :0001.1DC7 cld
    :0001.1DC8 lodsw // read a word
    :0001.1DC9 xor dx, ax // xor it into the checksum
    :0001.1DCB add dx, ax // and add it the the checksum
    :0001.1DCD loop 1DC8
    :0001.1DCF xor [0329], dx // xor the checksum to [0329]
    :0001.1DD3 je 1DE9 // jump if [0329] is now zero

    :0001.1DD5 mov cx, 000A
    :0001.1DD8 push bx
    :0001.1DD9 push cx
    :0001.1DDA mov ax, 0E07
    :0001.1DDD int 10 // Display char 0x07 on screen == beep
    :0001.1DDF xor cx, cx
    :0001.1DE1 loop 1DE1 // Wait a little while
    :0001.1DE3 pop cx
    :0001.1DE4 loop 1DD9 // Do this 10 times
    :0001.1DE6 pop bx
    :0001.1DE7 jmp 1DD5 // And when done 10 times, do it again, forever

    It's creating a sort of checksum of these 80 bytes, xors it into [0329]. If [0329]
    doesn't become 0 after the xor, the program will enter the ugly routine you can
    see at 1.1dd5. An endless loop with beeping. We don't want to go there, do we?
    Nice, we've found the checksum check for NE.QZ_! Will be usefull if we'll want to
    change anything in it. (And if they put an checksum on it, we probably will!)

    Data stored in the registry

    Anyway, we go on, and look what's happening if the checksum is correct, at 1.1de9
    It will read a bit, it calls GetTickCount and stores the result, and then there is
    this new checksum routine:


    :0001.1E19 lodsb
    :0001.1E1A stosb
    :0001.1E1B add dx, ax
    :0001.1E1D or ax, ax
    :0001.1E1F jne 1E19

    It does a simple checksum on the string "BRABOKER_NE1100898". "BRABOKER" is the
    publishers of the program, and "NE1" is the label of the original CD, "100898" is the
    date of the NE.EXE (and a lot of other files), in the format ddmmyy. The string
    "NE1100898" is hardcoded into NE.EXE. You'll see quite a lot of it, it will work as
    some kind of product code for the protected application. Anyway, after this, it adds
    ".CRC" to the string, and then a timer again...

    :0001.1E2E call far word ptr [075A] // call MMSYSTEM.TimeGetTime
    :0001.1E32 pop bx // Checksum of "NE1100898"
    :0001.1E33 xor dx, bx
    :0001.1E35 mov bx, 048E
    :0001.1E38 call 01F5 // Creates an ascii string...

    I haven't got any documentations about this function, but I have this strange
    feeling that it returns the current time. I know it returns a 32 bit value, though.
    The high word in dx and the low one in ax. What's returned in dx is xor:ed with
    the checksum of "BRABOKER_NE1100898", and then 1.1f5 is called. This function creates a
    ascii string of the 32 bit value dx and ax do together. Let me explain:

    "3DFE1204" << This is the created ascii string (a 32 bit hex number)
    "1204" << The 16 lowest bits are what TimeGetTime returned in ax
    "3DFE" << The 16 highest bits are what's returned in dx xor the checksum

    Then Shell.RegSetValue is called, and this string is stored in a key called
    "HKEY_CLASSES_ROOT\BRABOKER_NE1100898.CRC".

    Checksum for "NE.QZ_"

    Ok, follow the code. Lot's of interesting stuff here, we break for this one:

    :0001.1E53 xor ax, [0329]
    :0001.1E57 add dx, [0329]
    :0001.1E5B add dh, [35FE]

    Look, [0329]. That one should be zero if "NE.QZ_" has got the correct checksum.
    Ax and dx here are the result from that GetTickCount. As [0329] should be zero, the
    first two lines does nothing. Wonder what [35fe] is. I searched for it, and I
    only found one single spot, where it was cleared. Untouched, it's hardcoded to 0x37.
    I can't see directly what's happening in the area where it is cleared, but as we only
    got to alternatives, we can simply try both and earn a lot of time. However, my guess
    I that we leave both of the registers alone. (And as I actually how the story ends,
    you should soon see that my guesses are often very, very good.)

    NE.QZ_ called with data as argument

    Ok, I went on, and the next interesting part I found was this one:

    :0001.1E61 mov di, 02EB // pointer to "NE1100898"
    :0001.1E64 mov cx, 0040
    :0001.1E67 mov bx, FFF9 // = -7
    :0001.1E6A mov si, di
    :0001.1E6C xor eax, eax
    :0001.1E6F cld
    :0001.1E70 repnz
    :0001.1E71 scasb // scan the string for zero
    :0001.1E72 sub di, si
    :0001.1E74 lea cx, [bx+di] // cx = di - 7

    This one doesn't look important at all, but what it leaves in cx will be used right
    below, so I better present this as well. As you can see, the value in di will be one
    more than the actual string length, so the result in cx is length("NE1100898")+1-7=3.
    (Other products will of course have other strings here, making this number vary a bit)

    :0001.1E76 xor ebx, ebx
    :0001.1E79 lodsb // read a byte from "NE1100898"
    (..Uppercase routine...) // make it uppercase (censored)
    :0001.1E84 add ebx, eax // add it
    :0001.1E87 rol ebx, cl // rotate with our magic number
    :0001.1E8A loop 1E79
    :0001.1E8C mov ax, 3773 // 3773 is a kind of product number for the protected app
    :0001.1E8F add ax, bx
    :0001.1E91 ror ebx, 10
    :0001.1E95 sub ax, bx
    :0001.1E97 xor dx, ax

    Dx at this point holds the high word of the result from the GetTickCount call, and
    is now xored with a checksum of "NE1100898".

    :0001.1E99 pop si
    :0001.1E9A pop ax // pops the low word from GetTickCount back into ax
    :0001.1E9B push dx // high word from GetTickCount
    :0001.1E9C push ax // low word from GetTickCount
    :0001.1E9D pop ebx // observe that this is a 32 bit register
    (...)
    :0001.1EBA mov cx, 0008
    :0001.1EBD rol ebx, 04 // take 4 bits at a time
    :0001.1EC1 mov al , bl
    :0001.1EC3 and al, 0F
    :0001.1EC5 add al, 40 // and transform into an ascii char
    :0001.1EC7 stosb
    :0001.1EC8 loop 1EBD

    This little routine takes ax and dx together as one 32 bit register, goes trough it
    4 bits as a time, and for every 4 bits, it adds 40 and saves it like a byte. This
    gives a 8 bytes long string, working like this:

    dx = a 0 c d
    ax = 3 3 6 7
    4a 40 4c 4d 43 43 46 47 << The result. The meaning of this is to make
    the number in ascii format. This example
    will be perfectly readable as "J@LMCCFG".

    The result is stored as an argument to "NE.QZ_", creating a string that now reads
    "C:\PROGRAM FILES\NE\NE.QZ_ J@LMCCFG". (There is actually an extra space between
    the filename and the argument. Guess it's some kind of bug.)

    Then, just a couple of lines down, there it is:

    :0001.1ED5 call far word ptr [076E] // Call KRNL386.WinExec

    Our file "NE.QZ_" if finally run.

    Stop and summarize

    Let's sum up what data "NE.QZ_" has got when it's run now. There are two channels
    where it get's it's data: The key HKEY_CLASSES_ROOT\BRABOKER_NE1100898.CRC in the
    registry, and the command line argument.

    The registry keeps the 32 bit result from TimeGetTime, where the high word has
    been xored with a checksum from the string "BRABOKER_NE1100898".

    The command line argument keeps the 32 bit result from GetTickCount, perhaps destroyed
    by [0329] and [35fe] if we have been altering with "NE.QZ_", and where the high word
    has been xored with a checksum from the string "NE1100898" and the product number
    "3773".

    End of part one

    --------------------------------------------------------------------------------

    DISASSEMBLING NE.QZ_

    A great thing about these files are that you never need to search to find the
    fun parts. They're all over, the entire program is just a big protection. First
    of all, I just want to do a little comment on the second line in the new
    disassembly:

    :0040D145 call 0040D14A

    This call to the next line, is not really a call. It's a push 40d14a.
    Then there is a little checksum routine:

    :0040D150 xor ebp, ebp
    :0040D152 mov edi, 00000007

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:0040D17B(C)
    |
    :0040D157 mov esi, dword ptr [esp+10] // esi = 40d14a
    :0040D15B mov ecx, 00000068

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:0040D0EB(C)
    |
    :0040D160 xor bp, word ptr [esi] // xor each word to ebx
    :0040D163 xchg edi, ecx
    :0040D165 rol ebp, cl // rotate ebx dl bits left
    :0040D167 xchg edi, ecx
    :0040D169 cmp word ptr [esi], 15FF // skip checksum for CALLs
    :0040D16E jne 0040D176
    :0040D170 inc esi
    :0040D171 inc esi
    :0040D172 inc esi
    :0040D173 inc esi
    :0040D174 dec ecx
    :0040D175 dec ecx

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:0040D16E(C)
    |
    :0040D176 inc esi
    :0040D177 inc esi
    :0040D178 loop 0040D160
    :0040D17A dec edi
    :0040D17B jne 0040D157

    This ones makes a checksum of 0x68 words, starting at 40d14a, and down, trough itself
    Calls are skipped, as they may be reallocated. The whole thing is repeated 7 times,
    and each time the number of bits ebp is rotated by is decreased by one. The fact that
    it's checking itself does that we cannot change it, nor put a breakpoint somewhere in
    it, checking what the result is. But let's wait with this, and continue to look at the
    code further down.

    Next thing is a call to GetCommandLineA, the last 8 characters are decoded back to
    a 32 bit number and push upon the stack for later use.

    Then there's a call to GetTickCount, and the argument we got is decoded like this

    :0040D1B0 pop cx // low word from GetTickCount
    :0040D1B2 pop dx // high word
    :0040D1B4 sub eax, ecx // eax = our argument decoded
    :0040D1B6 shr eax, 10
    :0040D1B9 xor ax, dx
    :0040D1BC shl eax, 03
    :0040D1BF mov ebx, 001356F2
    :0040D1C4 add eax, ebx // and then 0x1356f2 is added
    :0040D1C6 mov edi, dword ptr [esp+10] // edi=40d14a
    :0040D1CA mov ebx, edi
    :0040D1CC add eax, dword ptr [ebx+000000D4] // [40d21e] = 02eb5b6b
    :0040D1D2 xor eax, ebp // xor with the checksum from above
    :0040D1D4 lea esi, dword ptr [edi+06] // esi=40d150
    :0040D1D7 mov ecx, 0000000C // 0x0c dwords
    :0040D1DC mov edi, eax

    :0040D1DE xor eax, dword ptr [esi]
    :0040D1E0 add edi, dword ptr [esi]
    :0040D1E2 inc esi
    :0040D1E3 inc esi
    :0040D1E4 inc esi
    :0040D1E5 inc esi
    :0040D1E6 loop 0040D1DE

    The protection adds the GetTickCount result to the argument just while it's transfered
    between the files, to make sure it will only work if it's read directly after it's been
    written. The same method is used for the data in the registry. Quite a nice one,
    actually, putting a breakpoint between when the data is written and when it is read
    will make the data outdated when the program gets the control back and continues.
    Let's take a closer look of what is done here.

    Our argument is first cleaned from GetTickCount, then 0x1356f2 is added, and then
    0x02eb5b6b is added, then it's xored with the checksum we got. After all this, it's
    copied into two registers. Then there is a new routine that goes trough the program,
    and itself, from 40d150 to 40d180, xoring each dword with one of these two registers,
    and adding the dword to the other register. Phew. What's next?

    :0040D1E8 lea ebp, dword ptr [ebx+0000382E] // 410978
    :0040D1EE add dword ptr [ebp+00], eax
    :0040D1F1 sub dword ptr [ebp+00], edi
    :0040D1F4 add dword ptr [ebp+00], ebx
    :0040D1F7 lea ebp, dword ptr [ebx+00003832] // 41097c
    :0040D1FD sub dword ptr [ebp+00], eax
    :0040D200 sub dword ptr [ebp+00], edi
    :0040D203 add dword ptr [ebp+00], ebx

    Here, the registers eax, edi and ebx are used to save something into two different
    locations. eax and edi are the result from the last checksum, and ebx is 40d14a.
    Then there's just one more thing before we can start reversing all those checksums
    and mathematics:

    :0040D20B sub eax, dword ptr [ebx+000000CC] // Another hardcoded value: 0x00000a16
    :0040D211 sub ebx, eax
    :0040D213 pop ebp
    :0040D214 jmp ebx // Jump to 40d14a - eax

    This is how to use checksums; add some, sub some, and then jump to them! Most people
    just check if they are good or bad, and then jumps or not, showing the whole world
    where. Ok, one could probably guess where this jump will land, but it's still a lot
    better.

    Time for reversing -- first checksum

    We will start with the first checksum of the code. The problem here is that it's
    checking itself and the whole code down to this jump, so there's no way we can put a
    breakpoint anywhere here. What I chose to do was to copy the checksum routine out of
    the area it checks, leaving it just like it should, and run it from a safe place.

    I loaded it up in Turbo Debugger, marked the whole area from the program entry point
    at 40d144 and down to the end of the whole program, at 40d222, just to be safe. Then
    copy, looked up, for a nice place to put it. And from 40c9cb to 40d01e (0x653 bytes!
    In decimal 1619 bytes!), there is this gigantic field of NOPs. I've got no idea why,
    but it's a nice place to put your own code!

    So I pasted it in the middle of this NOP-field. Then this CALL 40d14a has to be changed.
    It can't call the correct address, then our breakpoints obviously won't work, and it
    can't call our own little copy, because then it would make a checksum of that one. So I
    changed it into a PUSH 40d14a. Ok, then we're clear to run. I changed the eip to my own
    entry point, and put my first breakpoint at 40ca19, when the whole first checksum is
    done. I ran, and in ebp there is now 0xeb253578. Nice, first checksum down!

    Second checksum

    Now, there is this argument thing. We can't do that one yet, but we've still got another
    checksum we can look at, the one at 40ca7a. This one, however, adds it results into
    registers that already contain data. Bad data, to be specific, as the command line
    argument is very wrong. (I didn't even send it an argument.) So I had to put a
    breakpoint at 40ca78, and clear the two registers. Then a breakpoint at 40ca84, where
    I could read that eax is always XORed with 0xe8243481, and edi always is added with
    0x3272945d.

    Cheating the GetTickCount-trick

    Now, all we need is this data destoryed by the GetTickCount call. We've got to go back
    info NE.exe to catch this one. And how do we do next? Both calls to GetTickCount has
    to give the same return, so we better fill in the result ourselves instead! I chose
    0x01234567 as the current GetTickCount. (Actually, I tried zero at first, but it went
    negative at one spot, and then it was rotated into destruction, so the result went all
    wrong. I'll save you that mistake!)

    Load up NE.exe in Turbo Debugger, and change the CS:IP to 1.1e61.
    First at all, we've got some initializing to do.
    The registers has to be set up like this:

    es = ds
    dx = 0x0123 (High word of our faked GetTickCount result)

    Run until 1.1e97, and you'll see that 0x4d7d is going to be xored to our dx, and dx
    will then be 0x4c5e. Then ax with the low word from GetTickCount is poped, untouched,
    and together, they will make ebx. Instead of poping ax, I changed it to 0x4567, and
    in ebx I got 0x4c5e4567. Ok, done with NE.exe, now let's see what NE.QZ_ makes from
    this.

    Load it up and go to 40d1b4. cx and dx has just been POPed here,
    these two registers are the ax and dx we just looked at in NE.exe.
    Now initialize like this:

    eax = 0x01234567 (The result from GetTickCount in NE.QZ_)
    ecx = 0x4567 (Low word of our faked GetTickCount result)
    edx = 0x4c5e (High word of our faked GetTickCount result)
    ebp = 0xeb253578 (Checksum from the first checksum routine)

    I stepped trough the code. At 0x40d1c6, 0x40d14a is fetched from the stack.
    Fake this one, as our stack isn't like it should.
    Halt again before 0x40d1de. This is the second checksum routine.
    Skip it, and xor eax with 0xe8243481 and add 0x3272945d to edi (as
    we earlier could see is what this routine should do).

    eax: 0xe8242b3d xor 0xe8243481 = 0x1fbc
    edi: 0xe8242b3d + 0x3272945d = 0x1a96bf9a

    Now, let's se what's happening at 40d1e8.
    After stepping through the lines, the
    contents in 410978 is 0x40d138, and in 41097c it's 0x40d13e.
    Nice! Then jump down to 40d20b and look where the jump is going, too.
    It will be to 40c798. Now we've got
    everything we need. What this part of NE.QZ_ does is to save the two numbers
    at 410978 and 41097c, and then jumps to the right location, 40c798.
    As this is the only thing we need from this routinem let's make it a
    bit shorter! The values at 410978 are already
    hardcoded, so we could just change them at offset 0xd578 and 0xd57c in NE.QZ_.
    Then just change the program entry point to point to 40c798 instead.

    Taking care of the register data

    So, now I loaded the new version of NE.QZ_ into WDasm. And almost in the
    beginning, there is a quite expected line:

    * Reference To: winmm.timeGetTime, Ord:0000h
    |
    :0040C7D7 Call 0040830C
    :0040C7DC mov dword ptr [0040F884], eax

    Ok, timeGetTime is called, and stored in [0040f884]. I searched for usage of this
    address, and it's read again at this location:

    :0040C983 call 0040BAD8
    :0040C988 and eax, FFFF00FF
    :0040C98D mov dword ptr [0040F888], eax
    :0040C992 mov eax, dword ptr [0040F884] // timeGetTime()
    :0040C998 movzx edx, word ptr [0040F878]
    :0040C99F sub eax, edx
    :0040C9A1 shr eax, 10
    :0040C9A4 movzx edx, word ptr [0040F87A]
    :0040C9AB xor eax, edx
    :0040C9AD mov dword ptr [0040F878], eax
    :0040C9B3 or al, ah
    :0040C9B5 mov edx, dword ptr [0040F888]
    :0040C9BB xor dl, dh
    :0040C9BD add al, dl
    :0040C9BF shr edx, 10
    :0040C9C2 sub dh, dl
    :0040C9C4 sub al, dh
    :0040C9C6 mov byte ptr [0040F87C], al

    There's a couple of addresses here that we don't know what they are, but nevermind.
    I loaded it into Turbo Debugger again, and put a breakpoint at 40c97e, to look what's
    really happening here. At first run I got this MessageBox saying "Registry key
    invalid or not found!". Oh, it deletes the registry key after use. I ran regedit and
    wrote in a fake key, containing "12345678". Then I went back and ran it again, and this
    time it stops at my breakpoint. the call at 40C983 returns 0x250a4a67. [0040f878] is
    the low word of what's in the registry, and [40f87a] is the high word. Well, that's
    about all we need to know. Wonder what that call does, but as I couldn't see that at
    once, we'll wait with that one, and hope it gives the correct result already.

    So, time to make a fake registry entry, with a value based on our own number instead
    of timeGetTime. This one is a real easy one. We've only got to steal the checksum
    from the small routine in at 1.1e19. Easily done, and it is 0x4a5.
    This value should be xored with the high value of the timeGetTime. I decided my fake
    timeGetTime should be 0x12345678. XOR 0x4a5 into the high word, and we'll get
    0x16915678.
    Ok, so then I created the key "HKEY_CLASSES_ROOT\BRABOKER_NE1100898.CRC",
    with the contents "16915678", and then back to NE.QZ_.

    All done, the application runs

    I put a breakpoint at 40c983, and ran the program. At 40c992 I had to change the real
    timeGetTime() into my 0x12345678. Then I stepped down 'til the last line. Al is here
    0xf1, and that seems to be the only thing that's used from the registry code.
    I let the whole thing run from the point, and my program started up! We're in! Now, we
    can easily make the changes to make this file always just start the program. It doesn't
    even need to be started from NE.exe. However, the registry key is still checked, and
    even if we write the result over, it still will break if it can't find it. I tried to
    skip this little check, but I didn't do very well, and when the program came to the
    point where it is to remove the key, instead of returning an error, it removed ALL
    the keys in my registry. I had to reinstall my Windows. (But hey, we all have to do
    that every day anyway. That's what Windows' all about.) So be careful if you try
    something like this!

    Removing the entire envelop

    Ok, should I make the changes needed to make this whole thing run? It would have
    started without any problem, and the CDCops protection would bother no more. But, an
    extra file, just opening and decrypting the original file? Am I happy with that? No,
    I'm NOT! I WANT MORE!! Of course the whole CDCops protection has to be removed, or it
    would just felt wrong every time when I was to run this application, and I had to start
    this extra program, doing nothing but taking my time and my hard disc space.

    Finding where the program is kicked of is no real problem, but if you're in bad luck,
    it can take a while. I happened to stuble over it when I was looking for what that
    byte written into [0040F87C] (based on what's in the registry) really is. The location
    where it's used is here:

    :0040C263 mov al, byte ptr [0040F87C] // our 8-bit key
    :0040C268 add dword ptr [0040E2D0], 00000002 // make the jump 2 bytes further
    :0040C26F push ebp
    :0040C270 mov ebp, 00000004
    :0040C275 call dword ptr [0040E2D0] // looks like our key is used in here
    :0040C27B pop ebp
    :0040C27C sub dword ptr [0040E2D0], 00000002 // then change it back?
    :0040C283 pop edi
    :0040C284 pop esi
    :0040C285 pop ebx
    :0040C286 mov edx, dword ptr [ebp-04]
    :0040C289 mov eax, dword ptr [ebp-20]
    :0040C28C add eax, dword ptr [0040F608]
    :0040C292 mov ecx, dword ptr [ebp-1C]
    :0040C295 call 0040BFA8

    I didn't know what was in [40e2d0], so I ran Turbo Debugger once again. First of all,
    I had to write another registry key with "16915678", and remember to put that breakpoint
    at 40c992, to change the timeGetTime result into 0x12345678. Then, off to 40c263. Step
    down into the call at 40c275, and what do we see? Ah, the 2 bytes we skipped was an
    int 20h, probably would have crashed something if we'd jump at the wrong place. And
    what's next? An decrypting routine! Decrypting a section as big as 0x89e00 bytes!
    Could that be..? Of course it is! It's decrypting our code section in NE.W_X. Starting
    at 0x7709a8 and the whole way to 0x7fa7a8, there is our code section from NE.W_X.
    Better save this to disk! On my machine, I hade to wait 68 seconds for Turbo Debugger
    to save this block of memory. Terrible.

    Well, well! Exit Turbo Debugger, exit everything else. HEdit NE.W_X, find the right
    section (0x400 for my application), and paste the block. Save, and run. Everything
    runs perfectly as it should.

    THE END.

  7. #17
    پروفشنال Morteza_SOS's Avatar
    تاريخ عضويت
    Apr 2006
    پست ها
    577

    پيش فرض

    Crack Red Alert NO OrGiNal Cd



    NEEDED:
    SoftICE
    Hex ED
    Pen and Paper
    Heya welcome to another one of my great CD tuts , i'm gonna
    explain howto rip C&C2, this one i found a bit tricky certainly
    the hardess i've done, and that doesn't include Cdilla :P, anyways
    lets get on.
    This check had me stuck for a day or so and i had to sleep on it
    i ended up doing a instruction compare, and learning a new lesson
    on approachs to cd checks.
    Right lets get on and crack this baby, first of all take CD 1 and
    install, notice theres no installation type. Once the game has installed
    your notice that you have only 32mb installed on your computer, this
    can't be right we will need some more file(s) from the CD, anyway
    remove your CD and store safely, now run the game, what do we see?
    We see a error msg box which doesn't want to screen grab, n/m i'm
    sure you know what it looks like, now we have a Ok button and if we
    click it nothing happens apart from maybe a small screen refresh, this
    is good because we know that its checking something when we click
    OK, we'll just find out what its doing by setting our breakpoints now.
    Sooo what could it be doing? well our best bet is than its searching
    for a file, so lets check that by typing in SoftICE,
    BPX CreateFileA DO "D esp->4"
    you might think WTF does that do? well its break with a extra function
    you may already know what it means but for you unprivenged people
    i'll explain, this means break when the api CreateFileA is called,
    SoftICE will popup and DO a "D esp->4" thats dump 4th item on the
    stack pointer(ESP), well i think it means that :P
    Right now we are setup, click OK and see what happens, so what did
    happen? Well when i did it nothing, so i spent a few hours trying
    every single stupid API i could think of, but no joy, so then
    guess what, i figured out you needed a CD in the drive duh..
    hehe anyways back to the msg box, now make sure you have any old CD
    in the drive apart from the Red Alert ones :P, now make sure you have
    the breakpoint set, click OK, what happens, yay! a break.
    eEk! lotz of text............................

    ok so the program breaks what do you notice?, yes! in our
    dump window it says 'E:\main.mix' press F5 and bang it breaks again
    looking for the same file, then we are returned to the msg box, hmmm
    well we have a new mission to make the program read Main.mix
    from somewhere else, so lets start by copying it to our harddrive,
    i copied mine to C:\ the root directory would be best.
    Ok we now have the task of making it read of the C drive, cos i;m dumb
    and not very good at this CD check lark ) it took me a while to figure
    out it was GetDriveTypeA that finds the Cdrom Drive letter and stores it
    for later use, so all we have to do it make this API return the Harddisc
    as a CDROM, if you don't understand to Getdrivetype API i recommend you
    look it up in the Win32Api ref, you'll find it pushes a drive letter
    and when the api is called it will return its type, so for e.g it would
    push A:\ and return 2 in EAX as 2 means Removable Drive, 3 means Fixed
    and 5 means CDROM thats all we need know.
    So now exit to windows and set this break point BPX GetDriveTypeA DO "D esp"
    ok now click our RA95.exe icon cos thats what we are cracking by the way, hehe
    and you'll see SoftICE will break and the dump window will say A:\ press F12
    and you'll see this code :-
    015F:005B5090 89E0 ....................................MOV EAX,ESP
    015F:005B5092 50 ........................................PUSH EAX <--- Push Drive Letter
    015F:005B5093 885C2404 ...........................MOV [ESP+04],BL
    015F:005B5097 2EFF1560026E00 ...............CALL CS:[KERNEL32!GetDriveTypeA] <- Call API
    015F:005B509E 83F805 ...............................CMP EAX,05 <-- We are here
    015F:005B50A1 75DD .................................JNZ 005B5080
    015F:005B50A3 8B4668 ..............................MOV EAX,[ESI+68]
    Ok what can we see from that code??? well look!! its comparing the
    drive type to 5 a CDROM!, and A:\ isn't one so it jumps up, press F5
    and SoftICE will jump again, this time it says B:\ and you should
    get the general drift now, its comparing A:\ to Z:\ to see which
    is a CDROM Drive, this is done at the CMP EAX,05 Soooooo lets change
    this to CMP EAX,03, i tried pressing A and typing in CMP eax,03 but it
    just messed up because of the length of the instruction or some Sh*t,
    anyway we will have to change the HEX code, if you look it says 83F805
    hmm that means CMP EAX,05 so what ever could be CMP EAX,03 yes thats
    right its 83F803 so at this point create a copy of RA95.exe and call it Crack.exe and search for '83F80375DD' notice the extra JNZ
    code in there as well because there are several 83F805's in theres thats
    just to make we have to right one, anyway patch that and save.
    Now we have a exe which should in all theory run main.mix from C:\ ok now
    save your work and run the EXE and lets see if the game works!
    Ok so you just got back from rebooting your computer :P, or infact you
    just skipped a few lines ahead and read this and thought WHAT!
    hehehe, anyway if you ran it you would of noticed that the mouse pops
    up then disappears as if the .MIX is loading, and i can you for a fact
    it is, but i'm not allowed to tell you that because we don't know that
    :P, aaaaaaaaaanyway so what the #"£! is wrong with it????, Hmmmm well
    this is where i went to bed :P, next day i was like right.... tryed
    lots of sh*t out, but couldn't see SoftICE due to C&C2's colour palette
    which made SI invisable ,all black, so we have to resort to a instruction
    cmp which old pen and paper, don't know if other crackers ever do this
    but seems a bit lame :P, any i cracked it , right what we have to
    do is go back to our orignal exe (RA95) and hoax the CreateFileA to
    read in the .mix from the C drive and note down on paper all the jumps
    and if they jump or not, then we do the same again but this time, we
    insert the real CD before clicking OK, lets gooo ...
    Ok clear ya breakpoints and double click RA95.exe when we get to
    the error box goto into SoftICE and set the breakpoint BPX CreateFileA
    now leave SoftICE and click OK when it breaks type E ESP now a new
    window we open at the top of the screen and some where in there it will
    say E:\main.mix with your mouse click the E and type C over it now press
    enter, now press F12 to return to the code and you'll see that the
    CreateFileA api has return 40 or 30 in EAX to say it read 40/30 bytes
    instead of returning FFFFFFFF to say file not found, anyway from here on note
    down all our jumps and if they jump all not, heres my list
    004B67BF CMP EAX,-01
    004B67C2 JZ ......... NO JUMP
    004B67D6 JG ......... JUMP
    004B6804 JNZ ........ JUMP
    RET
    004B693A Mov
    004B693F JL ........ NO JUMP
    004B6943 JZ ........ NO JUMP
    004B6948 JZ ........ JUMP
    004B6956 JNZ ...... JUMP
    004B6ACD JLE ...... JUMP
    004B6C52 JZ ....... JUMP
    BLEH!! after that i though i'm not doing any more, i'm sure that was enough
    , ok now clear all breakpoints and back to the msg box, now insert your
    C&C2 CD 1 first before setting the breakpoints !! go into SoftICE and
    set BPX CreateFileA now leave SoftICE and click
    Ok and when it breaks at CreateFileA once again press F12 to get back to the
    code, and check all the exact same jumps for differences, heres my list.


    004B67BF CMP EAX,-01
    004B67C2 JZ ......... NO JUMP
    004B67D6 JG ......... JUMP
    004B6804 JNZ ........ NO JUMP
    BANG!! there is our difference heres the code

    015F:004B67FD E8AE910E00 ...........CALL 0059F9B0
    015F:004B6802 85C0 ........................TEST EAX,EAX
    015F:004B6804 75D7 ........................JNZ 004B67DD <--- BLEH!
    If you trace on your notice that you get stuck in a mad loop, and thats why
    when we ran our Crack.exe it jammed up, so what the hell!! lets NOP this jump
    out!!, open up your Crack.exe and search for '85C075D7' ok now replace with
    '85C09090' and Save now run our Crack.exe and they!!!!!!!!!! The Game works
    ~"£#£@$"£$ w00T!!! hehe, oh well, now that the game works, i went back
    to investigate that Call 0059F9B0 to find out what it was about, and it was
    just comparing C with A and some wired stuff, so i did a quick jump check
    with the real CD and didn't find much out, until i have just finished writting
    this doc.


    I found out that the call was comparing C with S and i thought and thought
    and remembered seeing a GetVolumeInformationA, so i looked up this and it
    gets the Name of a drive, this happens to be E:\ in this case, and the
    CD that i had in my drive was Shadow of the empire, the volume name was
    'SHADOWS' then i reliased the first letter of this was S !!!, clever eh?
    i quickly inserted a cd, that started with the letter R , guess what!!!
    the Call compared R to C !!!!!!!!!!!!11 thats it i cryed!! its checking to
    see if the first letter of the CD in the drive begins with a C , Jeezus!!
    i'm sooooo dumb, anyway we managed to defeat that with some lame jump compares
    and i thought i would write all this out just to show where people go wrong
    how people think and blah blah blah , if you just hex edit the getdrivetype
    bit to cmp eax,03 and insert a CD beginning with the letter C you'll find it
    works, but we have bypassed that anyway so thats it, a very long interesting
    tutorial which will have no doubt taught me the lesson checking that programs
    aren't checking the volume name, the API shall always be in the back of my
    mind now , anyway must stop typing,

  8. #18
    پروفشنال Morteza_SOS's Avatar
    تاريخ عضويت
    Apr 2006
    پست ها
    577

    پيش فرض

    Commandos

    HOW TO DEFEAT THE CD-LOCK PROTECTiON.
    written by (c) zoltan
    _ __ ___ __________________________________________________ ________________________________ ___ __ _

    -COMMANDOS: Behind Enemy Lines
    _ __ ___ __________________________________________________ ________________________________ ___ __ _

    TOOLS REQUIRED:
    -
    SoftIce 4.0
    - se below for url.

    W32Dasm, (if you want to folow)
    - se below for url.

    Hackers View 6.15
    - se below for url.

    Commandos: Behind Enemy Lines
    - buy it or get the ripp + original exe.

    _ __ ___ __________________________________________________ ________________________________ ___ __ _

    Briefing about cd-lock:

    Today nearly all games that get published has a form of protection called iSO protection (in the scene). It is there to prevent
    end-users for pirating cd's by just copying them at home with cd-burners. Today im going to Teach you how to "FiX" one of these
    protection's called CD-LOCK. How can you check if the cd you have is protected by CD-LOCK, simply explore your cd-drive and look
    for 4 huge (.afp) files.

    Inctroduction:

    Another famous game in the world, Commandos. This one was released to the public by CLASS PC on the 24th of June 1998. It's been
    availible for download on the internet ever since. Think i leeched it the same day, and got the original (protected) exe from
    some friends i have in the scene. I started cracking this (cd-check) like i thoght it was, because i haad never even heard of
    this cd-lock protection. Anyway i cracked it fairly easy, but i haad to admit to my self that this must been one of the hardest
    (cd-check, like i thoght) i haad ever done. Few months later i heard about this cd-lock protection, and i was like uhh ohh ?
    that protection got it's own name, cool! . I actuly love cracking protections that got their own name like CD-lock. Anyways
    enough shit chat, Start off by deleting the commandos.exe witch is Class' intro, or simply copy it over to another dir, if you
    want to collect that junk like it do. Now u delete the betasux.exe, because that is the cracked exe from Class, and we dont
    need it since we are going to crack this game ourselfs. Run commandos.exe, break on GetDriveTypea, press the start a new
    gamen and you should be landing here:


    * Referenced by a CALL at Address:
    |:0044CAFF <- where this whole protections was
    | \ called from ..
    :004949F0 83EC08 sub esp, 00000008
    :004949F3 A1D0266000 mov eax, dword ptr [006026D0]
    :004949F8 89442400 mov dword ptr [esp], eax
    :004949FC 53 push ebx
    :004949FD 56 push esi
    :004949FE B341 mov bl, 41
    :00494A00 57 push edi

    * Reference To: KERNEL32.GetDriveTypeA, Ord:00CEh
    |
    :00494A01 8B3514266600 mov esi, dword ptr [00662614]

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00494A8C(C)
    |
    :00494A07 8D44240C lea eax, dword ptr [esp+0C]
    :00494A0B 885C240C mov byte ptr [esp+0C], bl
    :00494A0F 50 push eax
    :00494A10 FFD6 call esi <- you are here.
    :00494A12 83F805 cmp eax, 00000005 <- compare if drive is a cd-drive
    :00494A15 7570 jne 00494A87 <- jump if not equal

    * Possible StringData Ref from Data Obj ->"rb" <- string that means READ
    |
    :00494A17 68900F5F00 push 005F0F90
    :00494A1C 881D10266000 mov byte ptr [00602610], bl

    * Possible StringData Ref from Data Obj ->"d:\TBTP.AFP" <- our friend.
    |
    :00494A22 6810266000 push 00602610 <- cdletter:\TBTP.AFP
    :00494A27 881D20266000 mov byte ptr [00602620], bl <- cdletter:\BBVN.AFP
    :00494A2D 881D30266000 mov byte ptr [00602630], bl <- cdletter:\ETAO.AFP
    :00494A33 881D40266000 mov byte ptr [00602640], bl <- cdletter:\BTBW.AFP
    :00494A39 E8D2A81300 call 005CF310 <- check if they are there ..
    :00494A3E 83C408 add esp, 00000008
    :00494A41 8BF8 mov edi, eax <- mov checksum result to edi
    :00494A43 85FF test edi, edi <- if edi == 1
    :00494A45 750A jne 00494A51 <- the files exists! ..
    :00494A47 C744241000000000 mov [esp+10], 00000000 <- mov [esp+10], 0 = file doesnt exist
    :00494A4F EB2E jmp 00494A7F <- jump and try again.

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00494A45(C)
    |
    :00494A51 6A00 push 00000000
    :00494A53 6800A08329 push 2983A000
    :00494A58 57 push edi
    :00494A59 E8C2AD1300 call 005CF820 <- SetFilePointer
    :00494A5E 83C40C add esp, 0000000C
    :00494A61 57 push edi
    :00494A62 E879AD1300 call 005CF7E0 <- ReadFile
    :00494A67 83C404 add esp, 00000004
    :00494A6A 33C9 xor ecx, ecx
    :00494A6C 83F829 cmp eax, 00000029 <- compare ...
    :00494A6F 0F94C1 sete cl
    :00494A72 894C2410 mov dword ptr [esp+10], ecx
    :00494A76 57 push edi
    :00494A77 E8F4A71300 call 005CF270
    :00494A7C 83C404 add esp, 00000004

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00494A4F(U)
    |
    :00494A7F 8B442410 mov eax, dword ptr [esp+10] <- if [esp+10] = 1 your good cracker.
    :00494A83 85C0 test eax, eax <- if eax == 1 then jump ..
    :00494A85 7514 jne 00494A9B <- continue with game ...

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00494A15(C)
    |
    :00494A87 FEC3 inc bl
    :00494A89 80FB5A cmp bl, 5A <- compare bl, 5Ah
    :00494A8C 0F8E75FFFFFF jle 00494A07 <- jump and try again with next drive.
    :00494A92 33C0 xor eax, eax <- baad cracker.
    :00494A94 5F pop edi
    :00494A95 5E pop esi
    :00494A96 5B pop ebx
    :00494A97 83C408 add esp, 00000008
    :00494A9A C3 ret



    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:00494A85(C)
    |
    :00494A9B B801000000 mov eax, 00000001 <- good cracker.
    :00494AA0 5F pop edi
    :00494AA1 5E pop esi
    :00494AA2 5B pop ebx
    :00494AA3 83C408 add esp, 00000008
    :00494AA6 C3 ret







    NOW. goto the code location where all this shit was called from, you should be here:




    * Referenced by a CALL at Addresses:
    |:00447E9C , :00448015 <- (here are the 2 calls)
    |
    :0044CAF0 83EC0C sub esp, 0000000C
    :0044CAF3 A1980A5F00 mov eax, dword ptr [005F0A98]
    :0044CAF8 85C0 test eax, eax
    :0044CAFA 90 nop
    :0044CAFB 53 push ebx
    :0044CAFC 56 push esi
    :0044CAFD 7413 je 0044CB12
    :0044CAFF E8EC7E0400 call 004949F0 <- call check ..
    :0044CB04 85C0 test eax, eax <- eax=1
    :0044CB06 740A je 0044CB12 <- continue with game ..
    :0044CB08 C705980A5F0000000000 mov dword ptr [005F0A98], 00000000

    * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
    |:0044CAFD(C), :0044CB06(C)
    |

    * Possible StringData Ref from Data Obj ->"rb"
    |
    :0044CB12 68900F5F00 push 005F0F90
    :0044CB17 BB00000000 mov ebx, 00000000

    * Possible StringData Ref from Data Obj ->"d:\TBTP.AFP"
    |
    :0044CB1C 6810266000 push 00602610
    :0044CB21 E8EA271800 call 005CF310
    :0044CB26 83C408 add esp, 00000008
    :0044CB29 8BF0 mov esi, eax
    more code more code ...who cares about it ...






    The best and the simplest way to crack this protection is probably to find where the protection was called
    from then just simply do like this:

    :00447E91 8883100D0000 mov byte ptr [ebx+00000D10], al
    :00447E97 E834321200 call 0056B0D0
    :00447E9C E84F4C0000 call 0044CAF0 <- where it was called from the first time.
    :00447EA1 85C0 test eax, eax <- eax=1 = good cracker, eax=0 = baad cracker
    :00447EA3 7418 je 00447EBD <- continue with game ..
    :00447EA5 8D442418 lea eax, dword ptr [esp+18]
    :00447EA9 8B4C2434 mov ecx, dword ptr [esp+34]


    Second Call:
    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:0044800C(U)
    |
    :00448015 E8D64A0000 call 0044CAF0 <- that's where it got called from the 2th time.
    :0044801A 85C0 test eax, eax <- same as above.
    :0044801C 7418 je 00448036 <- same as above..
    :0044801E 8D442418 lea eax, dword ptr [esp+18]



    You simply change both calls to mov eax, 1, and the game should run smooth.

  9. #19
    پروفشنال Morteza_SOS's Avatar
    تاريخ عضويت
    Apr 2006
    پست ها
    577

    پيش فرض

    .-----------------------------------.
    | PROJECT: PEACEMAKER´S TUTORIAL #1 |
    .___________________________________.

    Target:
    Commandos - Behind Enemy Lines *GERMAN* (Commandos - Hinter Feindlichen Linien)

    Tools needed:
    W32Disassembler
    Hex-Editor

    Comment:
    Both tools are available at
    کد:
    برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
    . I prefer to use HIEW, because it´s easier using
    HIEW for newbies. I hope you know how to read the offset in W32Dasm, if not, don´t read this tutorial
    because it is written for people with a little knowledge of what they are doing. Don´t mind

    Aim:
    To get blood in the German version

    Got all? Ok, then let´s start cracking the damn fucking game...

    Let´s give a try. If you are clever you already searched for your own, if there is any way to get
    blood in game, but you found nothing, i think. I tell you where to find the damn fucking option
    which says if blood or not. Go into the 'Output' dir in your commandos main dir. There open the file
    'Comando.cfg' with Notepad or any other Editor. How you can see are there four options given:

    .SONIDO [ .ACTIVO 1 .VOLUMEN 0.236220 ] <-------hm, nothing for us, just the volume of the sounds
    .MORALINA 1 <-----------------------------------Moralina? Sounds VERY interesting to me
    .NETGAMEPLAYER DEFAULT <------------------------How it looks only for multiplayer-games
    .SERVERADDRESS 0.0.0.0 <------------------------" " " " " " "

    Hmmmmm, do you think like i do? Yes, sure. Let´s change the 'MORALINA 1' to 'MORALINA 0'. Now start
    Commandos, and see what happens. Sh!t, a useless message which tell´s us that we need another version
    for our os (operating system). Replace the 0 with a 1 again and it can be started. Ok, now we know
    what it could be. Disassemble 'Comandos.exe' wait till it´s ready and click String Data Referneces.
    Now look for MORALINA. Got it?! Now double-click and Bingo! Now look around, scroll a lil´ bit down
    and you´ll see a jump. A jne (=jump if not equal). What is it good for? Hm, let´s try to NOP (means: it
    won´t do this point of code) it. Because then it won´t jump, when the program is at this point. OK, start
    HIEW, open the 'Comandos.exe' and press 2 times ENTER. Goto the offset, the jump is (in this case: 15D8BA)
    by pressing F5, there press F3 than F4 to edit the whole thing and delete the whole line and write instead
    of this NOP (NOP=No Operation). Press ENTER and do the same again. After this press again ENTER then ESC and
    then F9 to save. Let´s exit by pressing ESC again and try. Hm, sh!t, the same message we had before again...
    I hope you know, that the KERNEL32 Register can look for your Country settings. You need to know this for
    cracking Commandos. Ok, what now...? I´ll help you a lil´ bit. Go to W32Dasm and open the Imports.
    Now search for 'KERNEL32.GetSystemDefaultLangID', got it? Good. Double-Click and scroll down until you see this:

    :0044633D 81FF07040000 cmp edi, 00000407
    :00446343 7408 jne 004463CC

    Hm, you know what to do, or? We want Commandos, to jump to the game, whatever language you got on
    your os. So why not try to make the jne to a jmp? Now let´s change the jump if not equal to jump.
    Open HIEW, goto offset of the jump (45743), and then replace the jne with jmp. Save and start with
    the modified EXE and Bingo! We got blood in our game....

  10. #20
    پروفشنال Morteza_SOS's Avatar
    تاريخ عضويت
    Apr 2006
    پست ها
    577

    پيش فرض

    ================================================== ===============
    Title : Diablo (GAME)
    Version : 1.08 (should work with any)
    Protection : Cd Check (hidden in storm.dll)
    Producer :
    کد:
    برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
    Cracker : Zaks (tntpcclub@hotmail.com)
    Tools : W32Dasm, Hiew
    Difficulty : Very Easy (It is the same check routine as in Hellfire .. see tutorial 8)
    Tutorial No. : 9
    Font : Courier New (8)
    ================================================== ================================================== ===========

    1) Well, this tutorial will be very brief because the check routine here is exactly the same as it was in Hellfire. If there is anything unclear please download and read tutorial number 8. So we begin by installing Diablo. Patch it with 1.08 update. Copy file diabdat.mpq to your install dir. Make backup of your strom.dll and open it (the backup) with W32DAsm. Search for GetDriveTypeA and here we are :


    * Reference To: KERNEL32.GetDriveTypeA, Ord:0117h
    |
    :15017DDE FF156C110315 Call dword ptr [1503116C]
    :15017DE4 8D942430010000 lea edx, dword ptr [esp+00000130]
    :15017DEB 6804010000 push 00000104
    :15017DF0 52 push edx
    :15017DF1 8BF0 mov esi, eax
    :15017DF3 895C2424 mov dword ptr [esp+24], ebx
    * Reference To: storm.ExpFn0230()
    |
    :15017DF7 E8F4550000 call 1501D3F0
    :15017DFC 8D842430010000 lea eax, dword ptr [esp+00000130]
    :15017E03 6804010000 push 00000104
    :15017E08 8D4C2420 lea ecx, dword ptr [esp+20]
    :15017E0C 50 push eax
    :15017E0D 51 push ecx
    :15017E0E 53 push ebx
    :15017E0F 53 push ebx
    :15017E10 53 push ebx
    :15017E11 8D542428 lea edx, dword ptr [esp+28]
    :15017E15 53 push ebx
    :15017E16 52 push edx

    * Reference To: KERNEL32.GetVolumeInformationA, Ord:0191h
    |
    :15017E17 FF1570110315 Call dword ptr [15031170]
    :15017E1D 85C0 test eax, eax
    :15017E1F 7506 jne 15017E27
    :15017E21 895C2410 mov dword ptr [esp+10], ebx
    :15017E25 EB78 jmp 15017E9F

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:15017E1F(C)
    |
    :15017E27 8D442420 lea eax, dword ptr [esp+20]
    :15017E2B 8D4C2418 lea ecx, dword ptr [esp+18]
    :15017E2F 50 push eax
    :15017E30 8D542418 lea edx, dword ptr [esp+18]
    :15017E34 51 push ecx
    :15017E35 8D44242C lea eax, dword ptr [esp+2C]
    :15017E39 52 push edx
    :15017E3A 8D4C241C lea ecx, dword ptr [esp+1C]
    :15017E3E 50 push eax
    :15017E3F 51 push ecx
    :15017E40 895C2438 mov dword ptr [esp+38], ebx
    :15017E44 895C2428 mov dword ptr [esp+28], ebx
    :15017E48 895C242C mov dword ptr [esp+2C], ebx
    :15017E4C 895C2434 mov dword ptr [esp+34], ebx

    * Reference To: KERNEL32.GetDiskFreeSpaceA, Ord:0113h
    |
    :15017E50 FF1574110315 Call dword ptr [15031174]
    :15017E56 85C0 test eax, eax
    :15017E58 7506 jne 15017E60
    :15017E5A 895C2410 mov dword ptr [esp+10], ebx
    :15017E5E EB3F jmp 15017E9F

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:15017E58(C)
    |
    :15017E60 8B44241C mov eax, dword ptr [esp+1C]
    :15017E64 8B942430010000 mov edx, dword ptr [esp+00000130]
    :15017E6B 8B4C2418 mov ecx, dword ptr [esp+18]
    :15017E6F 8B6C2414 mov ebp, dword ptr [esp+14]
    :15017E73 83E004 and eax, 00000004
    :15017E76 33C2 xor eax, edx
    :15017E78 33C1 xor eax, ecx
    :15017E7A 33C5 xor eax, ebp
    :15017E7C 33C6 xor eax, esi
    :15017E7E 8BC8 mov ecx, eax
    :15017E80 C1E910 shr ecx, 10
    :15017E83 33C8 xor ecx, eax
    :15017E85 6681F9001F cmp cx, 1F00
    :15017E8A 740B je 15017E97 //This is the jump we will reverse or make EB
    :15017E8C 6681F90508 cmp cx, 0805
    :15017E91 895C2410 mov dword ptr [esp+10], ebx
    :15017E95 7508 jne 15017E9F

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:15017E8A(C)
    |
    :15017E97 C744241001000000 mov [esp+10], 00000001 //Goodguy is here

    * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
    |:15017E25(U), :15017E5E(U), :15017E95(C)
    |
    :15017E9F 8BAC2440020000 mov ebp, dword ptr [esp+00000240]
    :15017EA6 8BC5 mov eax, ebp
    :15017EA8 83E001 and eax, 00000001
    :15017EAB 8944241C mov dword ptr [esp+1C], eax
    :15017EAF 7427 je 15017ED8
    :15017EB1 395C2410 cmp dword ptr [esp+10], ebx
    :15017EB5 7521 jne 15017ED8
    :15017EB7 6A0F push 0000000F
    * Reference To: storm.ExpFn0203()
    |
    :15017EB9 E832B4FFFF call 150132F0
    :15017EBE 6858640315 push 15036458

    * Reference To: KERNEL32.LeaveCriticalSection, Ord:01DEh
    |
    :15017EC3 FF15E4110315 Call dword ptr [150311E4]
    :15017EC9 5F pop edi
    :15017ECA 5E pop esi
    :15017ECB 5D pop ebp
    :15017ECC 33C0 xor eax, eax
    :15017ECE 5B pop ebx
    :15017ECF 81C424020000 add esp, 00000224
    :15017ED5 C21000 ret 0010


    2) Well the same routine as it was in Hellfire. So open storm.dll with hiew. F4-decode, F5-go to 17E8A (the offset for je 15017E97), F3-edit and change 74 (je) with EB (jmp). So the program will always jump to Goodguy.
    I released this tutorial just to keep the tradition to release all my works with logs (tutorials).

    ================================================== ===============

Thread Information

Users Browsing this Thread

هم اکنون 1 کاربر در حال مشاهده این تاپیک میباشد. (0 کاربر عضو شده و 1 مهمان)

User Tag List

قوانين ايجاد تاپيک در انجمن

  • شما نمی توانید تاپیک ایحاد کنید
  • شما نمی توانید پاسخی ارسال کنید
  • شما نمی توانید فایل پیوست کنید
  • شما نمی توانید پاسخ خود را ویرایش کنید
  •