Diablo II 1.09b No Cd Code edits

This forum is for discussions on how to edit what can not be edited through the txt files, needless to say this isn't about battle net hacking.

Moderators: Nefarius, Havvoric

Post Reply

1
100%
 
Total votes: 1

FearedBliss
Posts: 82
Joined: Sat Oct 16, 2010 4:29 pm
United States of America

Diablo II 1.09b No Cd Code edits

Post by FearedBliss » Sun Mar 03, 2013 6:51 am

Hello all,

I've been trying to make modifications to Diablo II.exe for 1.09b in order for it not to use the CD. Onyx and other mods said in other posts that since Blizzard introduced the "no-cd patch" in 1.12+, that basically means that we can also make our own no-cd modifications for previous versions. So hopefully this post doesn't get locked or deleted.

Anyways, on to the content. I've been working and digging around the Diablo II.exe for 1.09b for about 10 hours now, also learning more about reverse engineering along the way. I'm not a beginner, but not pro either.

This is what I have so far:

Tools:
OllyDbg
PEiD
w32dasm

First I scanned the exe with PEiD to see if it was packed, and PEiD just said "Microsoft Visual C++ 6.0", which from some research means that it doesn't have any packing, it was just built with MSVC6.

When I opened the Diablo II.exe with File -> Open in OllyDbg, the base address is the usual 00400000, and Entry address is: 004014E3.

Initial searches for strings related to "Diablo II was unable to detect a Disc in your CD-ROM drive" and MessageBoxes with the title "CD-ROM drive error" with Olly and W32Dasm revealed that the address is around the following block:

Code: Select all

0040122D  |. 51             |PUSH ECX                                ; |pStartupInfo
0040122E  |. 6A 00          |PUSH 0                                  ; |CurrentDir = NULL
00401230  |. 6A 00          |PUSH 0                                  ; |pEnvironment = NULL
00401232  |. 6A 00          |PUSH 0                                  ; |CreationFlags = 0
00401234  |. 6A 01          |PUSH 1                                  ; |InheritHandles = TRUE
00401236  |. 6A 00          |PUSH 0                                  ; |pThreadSecurity = NULL
00401238  |. 6A 00          |PUSH 0                                  ; |pProcessSecurity = NULL
0040123A  |. 52             |PUSH EDX                                ; |CommandLine
0040123B  |. 6A 00          |PUSH 0                                  ; |ModuleFileName = NULL
0040123D  |. FF15 0C504000  |CALL DWORD PTR DS:[<&KERNEL32.CreatePro>; \Process is ready to be created and request will be sent to kernel
00401243  |. 85C0           |TEST EAX,EAX                            ;  tests something, the game should start here   <<<<<< Notice this
00401245  |. 75 4E          |JNZ SHORT Diablo_I.00401295             ;  jump is taken  <<<<<< Notice this
00401247  |. FF15 14504000  |CALL DWORD PTR DS:[<&KERNEL32.GetLastEr>; [GetLastError
0040124D  |. 8BF0           |MOV ESI,EAX
0040124F  |. 8D8424 8403000>|LEA EAX,DWORD PTR SS:[ESP+384]
00401256  |. 68 04010000    |PUSH 104
0040125B  |. 50             |PUSH EAX
0040125C  |. 6A 02          |PUSH 2
0040125E  |. 53             |PUSH EBX
0040125F  |. FFD5           |CALL EBP
00401261  |. 8D4C24 34      |LEA ECX,DWORD PTR SS:[ESP+34]
00401265  |. 68 04010000    |PUSH 104
the TEST EAX, EAX and JNZ appear to jump regardless of whether or not I put my expansion CD inside.

Code: Select all

0040123D  |. FF15 0C504000  |CALL DWORD PTR DS:[<&KERNEL32.CreatePro>; \Process is ready to be created and request will be sent to kernel
leads into the kernel32 module which in turn loads the game. I didn't find anything interesting in the kernel32 module, let alone I wont be modifying core os libraries.

Inside kernel32

Code: Select all

750A1088   FF75 18          PUSH DWORD PTR SS:[EBP+18]
750A108B   FF75 14          PUSH DWORD PTR SS:[EBP+14]
750A108E   FF75 10          PUSH DWORD PTR SS:[EBP+10]
750A1091   FF75 0C          PUSH DWORD PTR SS:[EBP+C]
750A1094   FF75 08          PUSH DWORD PTR SS:[EBP+8]
750A1097   6A 00            PUSH 0
750A1099   E8 01940100      CALL kernel32.CreateProcessInternalA     ; This is where the kernel actually creates the process
750A109E   5D               POP EBP
750A109F   C2 2800          RETN 28
750A10A2   90               NOP
750A10A3   90               NOP
750A10A4   90               NOP
750A10A5   90               NOP
When the module Diablo_I starts (What Diablo II.exe is called when Olly opens it), if you scroll down a little bit from the entry point, you will see the following:

Code: Select all

00401557  |. FF15 10504000  CALL DWORD PTR DS:[<&KERNEL32.GetCommand>; [GetCommandLineA
0040155D  |. A3 C8694000    MOV DWORD PTR DS:[4069C8],EAX
00401562  |. E8 FD0C0000    CALL Diablo_I.00402264
00401567  |. A3 B4644000    MOV DWORD PTR DS:[4064B4],EAX
0040156C  |. E8 A60A0000    CALL Diablo_I.00402017
00401571  |. E8 E8090000    CALL Diablo_I.00401F5E
00401576  |. E8 05070000    CALL Diablo_I.00401C80
0040157B  |. 8975 D0        MOV DWORD PTR SS:[EBP-30],ESI
0040157E  |. 8D45 A4        LEA EAX,DWORD PTR SS:[EBP-5C]
00401581  |. 50             PUSH EAX                                 ; /pStartupinfo
00401582  |. FF15 2C504000  CALL DWORD PTR DS:[<&KERNEL32.GetStartup>; \GetStartupInfoA
00401588  |. E8 79090000    CALL Diablo_I.00401F06
0040158D  |. 8945 9C        MOV DWORD PTR SS:[EBP-64],EAX
00401590  |. F645 D0 01     TEST BYTE PTR SS:[EBP-30],1
00401594  |. 74 06          JE SHORT Diablo_I.0040159C
00401596  |. 0FB745 D4      MOVZX EAX,WORD PTR SS:[EBP-2C]
0040159A  |. EB 03          JMP SHORT Diablo_I.0040159F
0040159C  |> 6A 0A          PUSH 0A
0040159E  |. 58             POP EAX
0040159F  |> 50             PUSH EAX                                 ; /Arg4
004015A0  |. FF75 9C        PUSH DWORD PTR SS:[EBP-64]               ; |Arg3
004015A3  |. 56             PUSH ESI                                 ; |Arg2
004015A4  |. 56             PUSH ESI                                 ; |/pModule
004015A5  |. FF15 28504000  CALL DWORD PTR DS:[<&KERNEL32.GetModuleH>; |\GetModuleHandleA
004015AB  |. 50             PUSH EAX                                 ; |Arg1
004015AC  |. E8 4FFAFFFF    CALL Diablo_I.00401000                   ; \<- Diablo stuff really starts here
004015B1  |. 8945 A0        MOV DWORD PTR SS:[EBP-60],EAX
004015B4  |. 50             PUSH EAX
004015B5  |. E8 F3060000    CALL Diablo_I.00401CAD
That is pretty much the main function. It just gets some information, and jumps right into other sections of the .exe.

I noticed that even if I put my CD inside and it loads D2, if I keep the game open and then continue stepping into the debugger, eventually it will go into code regarding cd-checks and it will end up saying to put in the disc (Even though the game is started and the CD is inside). Some code for that is the following:

Code: Select all

0040134C  |. 8D8C24 8403000>|LEA ECX,DWORD PTR SS:[ESP+384]
00401353  |. 6A 05          |PUSH 5                                  ; /Style = MB_RETRYCANCEL|MB_APPLMODAL
00401355  |. 8D5424 38      |LEA EDX,DWORD PTR SS:[ESP+38]           ; |
00401359  |. 51             |PUSH ECX                                ; |Title
0040135A  |. 52             |PUSH EDX                                ; |Text
0040135B  |. 6A 00          |PUSH 0                                  ; |hOwner = NULL
0040135D  |. FF15 AC504000  |CALL DWORD PTR DS:[<&USER32.MessageBoxA>; \MessageBox: Do you want to retry? or cancel message..
00401363  |. 83F8 02        |CMP EAX,2
00401366  |.^0F85 DFFCFFFF  \JNZ Diablo_I.0040104B                   ;  If not = to 0, then go back to top to load game
0040136C  |> 5D             POP EBP                                  ;  Case 1 of switch 004012CC
0040136D  |. 5B             POP EBX
0040136E  |> 8B4424 0C      MOV EAX,DWORD PTR SS:[ESP+C]
00401372  |. 50             PUSH EAX                                 ; /hObject
00401373  |. FF15 58504000  CALL DWORD PTR DS:[<&KERNEL32.CloseHandl>; \CloseHandle
00401379  |. 8BC6           MOV EAX,ESI
0040137B  |. 5F             POP EDI
0040137C  |. 5E             POP ESI
0040137D  |. 81C4 80060000  ADD ESP,680
00401383  \. C2 1000        RETN 10
I noticed that putting in the disc inside returns an EAX = 1 value, and not putting the disc inside and getting the "Please insert the disc" error messages and me clicking cancel ends up returning EAX = 0. I don't know if this is meaningful since it could just be the programs exit code (or code that the program will put out when it exits).

I retrieved strings by either loading the .exe with w32dasm and looking for "String Data References", or using Olly's -> Executable Modules -> (Right click Diablo II.exe) and click "View Resource Strings".

Before starting this project I thought it would be pretty easy, just going into the code and just inverting some stuff, I probably was thinking to naively haha.

- fearedbliss

User avatar
Necrolis
Senior Admin
Throne
Posts: 9125
Joined: Sat Mar 25, 2006 1:22 pm
Location: The Land of the Dead
Contact:
South Africa

Hand-picked

Re: Diablo II 1.09b No Cd Code edits

Post by Necrolis » Sun Mar 03, 2013 8:36 am

Diablo II.exe is a loader for game.exe, it doesn't actually do anything special. game.exe does all the actual magic, but is packed with securom.

IMO, it is a thousand times easier to just use a mini image of the D2 CD, this solution works for any version as well.
Image
Netiquette, Do you USE it?!?! | Nefarius' Fixed TXT Files | Terms Of Service
Blackened | Day of Death | D2GFEx
"What was yours is mine. Your land, your people, and now your life." - Lim-Dul, the Necromancer
Judgement is Final, Death is Eternal

FearedBliss
Posts: 82
Joined: Sat Oct 16, 2010 4:29 pm
United States of America

Re: Diablo II 1.09b No Cd Code edits

Post by FearedBliss » Sun Mar 03, 2013 4:50 pm

Hey Necrolis,

I don't know how to make a mini-image and actually never heard of it. I made a full image of the expansion cd both in .iso and .mdf formats. The .iso one doesn't work probably because the bad blocks for cd verification for autocorrected. However, the .mdf one made by Alcohol 120% works perfectly fine. Alcohol 120% also detected that my 1.07 CD has SecuROM 4 or less.

Although depending how difficult this is, I might as well just keep trying to figure this out for learning purposes. It would be a nice way for me to get better with ASM and reverse engineering.

EDIT: Just researched how to make a mini-image. I must say, whoever came up with that was a clever thinker haha.

FearedBliss
Posts: 82
Joined: Sat Oct 16, 2010 4:29 pm
United States of America

Re: Diablo II 1.09b No Cd Code edits

Post by FearedBliss » Mon Mar 04, 2013 4:15 am

I don't know if it's correct for me to make a new post (double post in a sense) due to the amount of time between both posts. If I can't do that, please let me know and I will merge and delete this post.

So more progress on me digging around the Game.exe this time and spending an additional 10-15 hours testing/debugging/and researching all over the interwebs.

I downloaded a few additional tools:

ImportREC (To rebuild Game.exe ITA table)
LordPE
A few packer detectors (RDG, Protection iD, ExeinfoPE, Detect it Easy)

XDG Detected: Petite v2.2 (which is wrong)
Protection iD Detected: SecuROM 04.54.00 0093 which is correct.
Other packers just said: Microsoft Visual C++ 6 (and maybe Overlay), which doesn't help at all.

You can verify it's that version of SecuROM by doing a hex edit search for "AddD" and you will end up with the numbers 04.54.00 0093.

Opening up Olly and setting a Breakpoint on Access in the line below PE Header (for Game) in the Memory Map of Olly, which should be the .text line, and running 2 slices of execution will get you the address: 415089, and from reading a few SecuROM oriented guides, they all say that this first address is the OEP address. Around it looks like this:

Code: Select all

00415084  |.  56            PUSH ESI
00415085  |.  57            PUSH EDI
00415086  |.  8B5D 0C       MOV EBX,DWORD PTR SS:[EBP+C]
00415089  |.  8B03          MOV EAX,DWORD PTR DS:[EBX] <<<<<
0041508B  |.  8B45 18       MOV EAX,DWORD PTR SS:[EBP+18]
0041508E  |.  50            PUSH EAX
0041508F  |.  8B4D 14       MOV ECX,DWORD PTR SS:[EBP+14]
Normally, if I run Game.exe by double clicking it, it will work, but running it through the debugger doesn't work because I'm thinking that there is an anti-debugger protection. If you run 2-3 normal slices of operations, you will reach a IDIV ECX which is a division by zero. Thus execution is halted here.

Anyways, after I got the 415089 which I assumed is my OEP address, I proceeded to dump the file. I dumped the file with OllyDump and I unchecked the "Rebuild Import". After the file was saved, I got the first function's address that was located from the 415089 line which is:

Code: Select all

0041509B    8B4D 08         MOV ECX,DWORD PTR SS:[EBP+8]
0041509E    51              PUSH ECX
0041509F    FF15 60074500   CALL DWORD PTR DS:[450760]               ; kernel32.ReadProcessMemory <<<<<
004150A5    5F              POP EDI
004150A6    5E              POP ESI
The "450760" will help us when rebuilding the ITA table.

I then continued to open ImportREC and opened the Game.exe from the list, after that I put the OEP: 15089 and RVAV: 50760 and press GetImport. I then clicked fix-dump, and tried the resulting Game.exe, but it crashes with a StackHash error. So no success.

I also played around with OllyDump/LordPE/ImportREC and different permutation of settings and different "possible" OEPs but to no prevail.

I feel like I'm getting closer, but I might still be very far away, and since I already made the proper disc image from my physical d2 exp 1.07 copys (made with alcohol 120% since it supports SecuROM 4/5/7) I can play 1.09 just fine. It would have been nice to figure this out but eeh, to much time already spent on this compared to me just playing with the .mdf/s that I created.

Just wanted to put my findings on here.

- FearedBliss

User avatar
seltsamuel
Posts: 80
Joined: Sat Feb 10, 2007 8:52 am

Re: Diablo II 1.09b No Cd Code edits

Post by seltsamuel » Thu Mar 07, 2013 11:07 am

Hi,

why reinventing the wheel again?
Cornii and i did already release a backported game.exe for older d2 versions. Just search for this..
Or simply use D2SE Modmanager.

Greetings

Seltsamuel

FearedBliss
Posts: 82
Joined: Sat Oct 16, 2010 4:29 pm
United States of America

Re: Diablo II 1.09b No Cd Code edits

Post by FearedBliss » Thu Mar 07, 2013 9:52 pm

Hey Selt,

It's not about reinventing the wheel, I can't find any information on doing this, and I wanted to learn how to do some reverse engineering so it's about the learning experience of being able to remove SecuROM and let D2 play with no CD. Can you please post your notes and methods of how you disabled SecuROM (Unpacked, Rebuilt ITA) and then found where in the code you need to check to disable the No-CD check? (Posting the unpacking of this SecuROM and rebuilding the ITA alone would be a huge help for me and would help my understanding of how this works).

- fearedbliss

User avatar
ChaosMarc
Dark Alliance Beta Test
Champion of the Light
Posts: 256
Joined: Fri May 28, 2004 2:00 pm
Germany

Re: Diablo II 1.09b No Cd Code edits

Post by ChaosMarc » Thu Mar 07, 2013 10:10 pm

I don't think they did it that way.
as far as I grasped it corni and selt used one of the unprotected game.exe (1.12a and above) and modified it to work with versions below

User avatar
seltsamuel
Posts: 80
Joined: Sat Feb 10, 2007 8:52 am

Re: Diablo II 1.09b No Cd Code edits

Post by seltsamuel » Thu Mar 07, 2013 10:46 pm

Hi,

yes, themastercaster is right. Beside of this no one here is allowed to tell you how to crack a copyprotection that is still actively in use in other titles.. this has nothing to do with modding but with piracy. The way we went is .. take a 1.12a game.exe and modify the importtables so it works with older game.dlls ..switch all ordinals and such. This way we had not to change a single line of code copyrighted by blizzard ^ ^.

Greetings

Seltsamuel

FearedBliss
Posts: 82
Joined: Sat Oct 16, 2010 4:29 pm
United States of America

Re: Diablo II 1.09b No Cd Code edits

Post by FearedBliss » Fri Mar 08, 2013 5:06 am

Hmm, I suppose you are right Selt about the piracy.

Well thanks for the info :)

batmanReturns
Posts: 2
Joined: Sun Jun 18, 2017 10:39 pm

Re: Diablo II 1.09b No Cd Code edits

Post by batmanReturns » Mon Jun 19, 2017 11:19 pm

FearedBliss" wrote:Hello all,

I've been trying to make modifications to Diablo II.exe for 1.09b in order for it not to use the CD. Onyx and other mods said in other posts that since Blizzard introduced the "no-cd patch" in 1.12+, that basically means that we can also make our own no-cd modifications for previous versions. So hopefully this post doesn't get locked or deleted.

Anyways, on to the content. I've been working and digging around the Diablo II.exe for 1.09b for about 10 hours now, also learning more about reverse engineering along the way. I'm not a beginner, but not pro either.

This is what I have so far:

Tools:
OllyDbg
PEiD
w32dasm

First I scanned the exe with PEiD to see if it was packed, and PEiD just said "Microsoft Visual C++ 6.0", which from some research means that it doesn't have any packing, it was just built with MSVC6.

When I opened the Diablo II.exe with File -> Open in OllyDbg, the base address is the usual 00400000, and Entry address is: 004014E3.

Initial searches for strings related to "Diablo II was unable to detect a Disc in your CD-ROM drive" and MessageBoxes with the title "CD-ROM drive error" with Olly and W32Dasm revealed that the address is around the following block:

Code: Select all

0040122D  |. 51             |PUSH ECX                                ; |pStartupInfo
0040122E  |. 6A 00          |PUSH 0                                  ; |CurrentDir = NULL
00401230  |. 6A 00          |PUSH 0                                  ; |pEnvironment = NULL
00401232  |. 6A 00          |PUSH 0                                  ; |CreationFlags = 0
00401234  |. 6A 01          |PUSH 1                                  ; |InheritHandles = TRUE
00401236  |. 6A 00          |PUSH 0                                  ; |pThreadSecurity = NULL
00401238  |. 6A 00          |PUSH 0                                  ; |pProcessSecurity = NULL
0040123A  |. 52             |PUSH EDX                                ; |CommandLine
0040123B  |. 6A 00          |PUSH 0                                  ; |ModuleFileName = NULL
0040123D  |. FF15 0C504000  |CALL DWORD PTR DS:[<&KERNEL32.CreatePro>; \Process is ready to be created and request will be sent to kernel
00401243  |. 85C0           |TEST EAX,EAX                            ;  tests something, the game should start here   <<<<<< Notice this
00401245  |. 75 4E          |JNZ SHORT Diablo_I.00401295             ;  jump is taken  <<<<<< Notice this
00401247  |. FF15 14504000  |CALL DWORD PTR DS:[<&KERNEL32.GetLastEr>; [GetLastError
0040124D  |. 8BF0           |MOV ESI,EAX
0040124F  |. 8D8424 8403000>|LEA EAX,DWORD PTR SS:[ESP+384]
00401256  |. 68 04010000    |PUSH 104
0040125B  |. 50             |PUSH EAX
0040125C  |. 6A 02          |PUSH 2
0040125E  |. 53             |PUSH EBX
0040125F  |. FFD5           |CALL EBP
00401261  |. 8D4C24 34      |LEA ECX,DWORD PTR SS:[ESP+34]
00401265  |. 68 04010000    |PUSH 104
the TEST EAX, EAX and JNZ appear to jump regardless of whether or not I put my expansion CD inside.

Code: Select all

0040123D  |. FF15 0C504000  |CALL DWORD PTR DS:[<&KERNEL32.CreatePro>; \Process is ready to be created and request will be sent to kernel
leads into the kernel32 module which in turn loads the game. I didn't find anything interesting in the kernel32 module, let alone I wont be modifying core os libraries.

Inside kernel32

Code: Select all

750A1088   FF75 18          PUSH DWORD PTR SS:[EBP+18]
750A108B   FF75 14          PUSH DWORD PTR SS:[EBP+14]
750A108E   FF75 10          PUSH DWORD PTR SS:[EBP+10]
750A1091   FF75 0C          PUSH DWORD PTR SS:[EBP+C]
750A1094   FF75 08          PUSH DWORD PTR SS:[EBP+8]
750A1097   6A 00            PUSH 0
750A1099   E8 01940100      CALL kernel32.CreateProcessInternalA     ; This is where the kernel actually creates the process
750A109E   5D               POP EBP
750A109F   C2 2800          RETN 28
750A10A2   90               NOP
750A10A3   90               NOP
750A10A4   90               NOP
750A10A5   90               NOP
When the module Diablo_I starts (What Diablo II.exe is called when Olly opens it), if you scroll down a little bit from the entry point, you will see the following:

Code: Select all

00401557  |. FF15 10504000  CALL DWORD PTR DS:[<&KERNEL32.GetCommand>; [GetCommandLineA
0040155D  |. A3 C8694000    MOV DWORD PTR DS:[4069C8],EAX
00401562  |. E8 FD0C0000    CALL Diablo_I.00402264
00401567  |. A3 B4644000    MOV DWORD PTR DS:[4064B4],EAX
0040156C  |. E8 A60A0000    CALL Diablo_I.00402017
00401571  |. E8 E8090000    CALL Diablo_I.00401F5E
00401576  |. E8 05070000    CALL Diablo_I.00401C80
0040157B  |. 8975 D0        MOV DWORD PTR SS:[EBP-30],ESI
0040157E  |. 8D45 A4        LEA EAX,DWORD PTR SS:[EBP-5C]
00401581  |. 50             PUSH EAX                                 ; /pStartupinfo
00401582  |. FF15 2C504000  CALL DWORD PTR DS:[<&KERNEL32.GetStartup>; \GetStartupInfoA
00401588  |. E8 79090000    CALL Diablo_I.00401F06
0040158D  |. 8945 9C        MOV DWORD PTR SS:[EBP-64],EAX
00401590  |. F645 D0 01     TEST BYTE PTR SS:[EBP-30],1
00401594  |. 74 06          JE SHORT Diablo_I.0040159C
00401596  |. 0FB745 D4      MOVZX EAX,WORD PTR SS:[EBP-2C]
0040159A  |. EB 03          JMP SHORT Diablo_I.0040159F
0040159C  |> 6A 0A          PUSH 0A
0040159E  |. 58             POP EAX
0040159F  |> 50             PUSH EAX                                 ; /Arg4
004015A0  |. FF75 9C        PUSH DWORD PTR SS:[EBP-64]               ; |Arg3
004015A3  |. 56             PUSH ESI                                 ; |Arg2
004015A4  |. 56             PUSH ESI                                 ; |/pModule
004015A5  |. FF15 28504000  CALL DWORD PTR DS:[<&KERNEL32.GetModuleH>; |\GetModuleHandleA
004015AB  |. 50             PUSH EAX                                 ; |Arg1
004015AC  |. E8 4FFAFFFF    CALL Diablo_I.00401000                   ; \<- Diablo stuff really starts here
004015B1  |. 8945 A0        MOV DWORD PTR SS:[EBP-60],EAX
004015B4  |. 50             PUSH EAX
004015B5  |. E8 F3060000    CALL Diablo_I.00401CAD
That is pretty much the main function. It just gets some information, and jumps right into other sections of the .exe.

I noticed that even if I put my CD inside and it loads D2, if I keep the game open and then continue stepping into the debugger, eventually it will go into code regarding cd-checks and it will end up saying to put in the disc (Even though the game is started and the CD is inside). Some code for that is the following:

Code: Select all

0040134C  |. 8D8C24 8403000>|LEA ECX,DWORD PTR SS:[ESP+384]
00401353  |. 6A 05          |PUSH 5                                  ; /Style = MB_RETRYCANCEL|MB_APPLMODAL
00401355  |. 8D5424 38      |LEA EDX,DWORD PTR SS:[ESP+38]           ; |
00401359  |. 51             |PUSH ECX                                ; |Title
0040135A  |. 52             |PUSH EDX                                ; |Text
0040135B  |. 6A 00          |PUSH 0                                  ; |hOwner = NULL
0040135D  |. FF15 AC504000  |CALL DWORD PTR DS:[<&USER32.MessageBoxA>; \MessageBox: Do you want to retry? or cancel message..
00401363  |. 83F8 02        |CMP EAX,2
00401366  |.^0F85 DFFCFFFF  \JNZ Diablo_I.0040104B                   ;  If not = to 0, then go back to top to load game
0040136C  |> 5D             POP EBP                                  ;  Case 1 of switch 004012CC
0040136D  |. 5B             POP EBX
0040136E  |> 8B4424 0C      MOV EAX,DWORD PTR SS:[ESP+C]
00401372  |. 50             PUSH EAX                                 ; /hObject
00401373  |. FF15 58504000  CALL DWORD PTR DS:[<&KERNEL32.CloseHandl>; \CloseHandle
00401379  |. 8BC6           MOV EAX,ESI
0040137B  |. 5F             POP EDI
0040137C  |. 5E             POP ESI
0040137D  |. 81C4 80060000  ADD ESP,680
00401383  \. C2 1000        RETN 10
I noticed that putting in the disc inside returns an EAX = 1 value, and not putting the disc inside and getting the "Please insert the disc" error messages and me clicking cancel ends up returning EAX = 0. I don't know if this is meaningful since it could just be the programs exit code (or code that the program will put out when it exits).

I retrieved strings by either loading the .exe with w32dasm and looking for "String Data References", or using Olly's -> Executable Modules -> (Right click Diablo II.exe) and click "View Resource Strings".

Before starting this project I thought it would be pretty easy, just going into the code and just inverting some stuff, I probably was thinking to naively haha.

- fearedbliss

Friend, I am working on a "No-CD" patch for D2 LoD version 1.09d (yours is 1.09b) and I would really like to work together since I am also stopped. My findings indicate that there are some additional validation on "Diablo II.exe"

Code: Select all

PEiD
	Compiled: "Microsoft Visual C++ 6.0"
	Base Address:00400000
	EntryPoint: 004014E3
---------------------------------
Since I am using "Diablo II LoD" in Spanish version the error message goes in spanish ("Error al leer el CD-ROM.")
Here we go...

WDASM - Search for "leer"

* Possible Reference to String Resource ID=00002: "Error al leer el CD-ROM."
                                  |
:004022A3 C7054886400002000000    mov dword ptr [00408648], 00000002
:004022AD E98F000000              jmp 00402341
	
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040227D(C)

---------------------------------
I found there are 3 interesting jump's (JNZ):
0040227B |. 3BC3 CMP EAX,EBX ; PRIMERA COMPARACION (CMP)
0040227D 75 33 JNZ SHORT Copia_de.004022B2 ; Cambiamos JNZ por JMP
---
004022B2 |> \83F8 01 CMP EAX,1 ; SEGUNDA COMPARACION (CMP)
004022B5 0F85 81000000 JNZ Copia_de.0040233C ; Cambiamos JNZ por JMP
---
0040233C |> \83F8 02 CMP EAX,2 ; TERCERA COMPARACION (CMP)
0040233F 75 4C JNZ SHORT Copia_de.0040238D ; Cambiamos JNZ por JMP
---
Now, I Assembled on this directions replacing JNZ by JMP but it sends me a crash error on "Diablo II.exe".

B!

User avatar
Necrolis
Senior Admin
Throne
Posts: 9125
Joined: Sat Mar 25, 2006 1:22 pm
Location: The Land of the Dead
Contact:
South Africa

Hand-picked

Re: Diablo II 1.09b No Cd Code edits

Post by Necrolis » Tue Jun 20, 2017 3:31 pm

As I mentioned in my first post in this thread, there is no need to bother with Diablo II.exe, just use game.exe directly. From there, all you need to do is remove the securom packing (or have a look here for premade ones). The only thing one might want to fix after that is the CD check in D2Win which are simple to nop out.
Image
Netiquette, Do you USE it?!?! | Nefarius' Fixed TXT Files | Terms Of Service
Blackened | Day of Death | D2GFEx
"What was yours is mine. Your land, your people, and now your life." - Lim-Dul, the Necromancer
Judgement is Final, Death is Eternal

User avatar
GalaXyHaXz
Hosted Forum Moderator
Crusader
Posts: 54
Joined: Mon Apr 04, 2011 3:44 am

Re: Diablo II 1.09b No Cd Code edits

Post by GalaXyHaXz » Sun Jul 23, 2017 6:10 pm

Diablo II doesn't actually have mandatory CD checks. Diablo II.exe attempts to launch Game.exe and if it fails to decrypt (no CD in drive) it will throw an error. Once the securom is unpacked from Game.exe, the game will attempt to start. It will search the current directory for all the .MPQ files and if it fails to find them, it will then check the CD path. If it fails to find them there, it will throw an error.

All you need to do is unpack the securom and the game will work without the CD. The no-CD pack I made that Necrolis posted does just that. The securom was unpacked and the un-needed code was deleted.

All versions of Diablo II use SecuRom v1. This is a really old protection and there aren't any modern cracking tools for it. I cracked the protection by doing this:

1) You need a physical Windows 9x computer capable of running D2 (Virtual machines DO NOT WORK)
2) Patch to the version you want to crack and insert the Play Disc
3) Load up the program "Procdump32"
4) Select "unpack executable" and choose "Petite 2.1". Save the file in the install directory.
5) Click "Brahma Server"
6) Open the Securom folder and start LOADER.EXE (This program uses .VXD which WON'T WORK UNDER WINDOWS NT)
7) The Brahma server will dump the unpacked executable in a few minutes. Save it somewhere.
8) The last step is to fixup the imports. I had to do it manually but there are probably tools out there.
9) The game will now run without the CD. No further edits required!
1.09b Fixup: Download
UnSecurom'd .exe for patches 1.00-1.11b: Download
My very first mod, SLASH: Download

User avatar
XORcist
Posts: 8
Joined: Mon Aug 29, 2016 11:57 am

Re: Diablo II 1.09b No Cd Code edits

Post by XORcist » Mon Aug 14, 2017 2:35 pm

@GalaXyHaXz

Thanks a lot for your work on the NoCD_Pack of fixed game.exe files for pre 1.12 games, they work fantastic.

:D

EDIT: I forgot to mention that I also copied the noCD version of game.exe into the mpq archive.. I think it was D2Char.mpq ? It seems like D2Win also checks the MPQ archived version of Game.exe in old versions & gives some minor hickups if you don't replace it, (or nop out the code as Necrolis mentioned).

User avatar
GalaXyHaXz
Hosted Forum Moderator
Crusader
Posts: 54
Joined: Mon Apr 04, 2011 3:44 am

Re: Diablo II 1.09b No Cd Code edits

Post by GalaXyHaXz » Thu Aug 17, 2017 2:26 pm

The game.exe in the mpq file is not checked. This file is the original install file for the game (1.00 for classic and 1.07 for lod). I think these are extracted during the initial install or using -install. Nonetheless, only game.exe is needed as well as the MPQ files copied off the CD. Ive never had to modify any of the dll files. Blizzard didn't try too hard to copy protect the game. By 1.11 however, securom grew to 1mb. Once it is decrypted, game.exe becomes a mere 60kb just like 1.12!
1.09b Fixup: Download
UnSecurom'd .exe for patches 1.00-1.11b: Download
My very first mod, SLASH: Download

Post Reply

Return to “Code Editing”