NAME
Diablo II Cube Exploit — A client-side hack to open the Horadric Cube window anywhere, potentially paving the way for item duplication exploits.
METADATA
| Platform: | Diablo II |
| Era: | 2001-2002 |
| Status: | Source available |
SYNOPSIS
Cube.asm — Assembly code to force-open the Horadric Cube interface.
DESCRIPTION
The Cube Exploit allowed a player to open the Horadric Cube window at any time using a hotkey (INSERT), even if they weren’t clicking on a physical cube in their inventory.
The primary goal of this research was to find a desynchronization between the client and the server’s state of the cube, which was a common starting point for “Duping” (Item Duplication) methods. This hack automated the complex sequence of opening the interface client-side while properly notifying the server (HOME key) to avoid instant disconnection.
KEY FEATURES
- Client-Side Interface Injection — Forces the game engine to render the cube UI on demand.
- Server Sync Packets — Manually sends the required notification packets to simulate a legal cube opening.
- Hotkeys — mapped to
INSERTandHOMEfor precise control over the exploit sequence.
NOTES
This hack demonstrates how the Diablo II client could be manipulated into displaying UI elements that the server hadn’t explicitly allowed, highlighting the “thin client” vulnerabilities of the v1.09 engine.
ATTACHMENTS (Browsing /usr/games/)
.386
.model flat,stdcall
option casemap:none
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
ApplyProc proto :DWORD
UnloadProc proto :DWORD
GetHandleProc proto
SpyCheckProc proto :DWORD
InfoProc proto :DWORD,:DWORD,:DWORD,:DWORD
AboutProc proto :DWORD,:DWORD,:DWORD,:DWORD
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
;Define macro
szText MACRO Name, Text:VARARG
LOCAL lbl
jmp lbl
Name db Text,0
lbl:
ENDM
.data
ClassName db "Cube",0
AppName db "Cube Exploit v1.1",0
DlgName db "MyDialog",0
AboutDlgName db "AboutBox",0 ;About dialog
InfoDlgName db "InfoBox",0 ;Hack info dialog
;String to search
GameName db "Diablo II",0
;ERRORS
err_cap db "ERROR",0
err_mustRun db "Diablo II must be running! ",0
err_writing db "DLLs are not totally loaded in memory. ",13,10
db " Join a game first",0
;Button messages
appliedMsg db "Applied",0
applyMsg db "Apply",0
infoText db " This patch allows you to directly put the cube",13,10
db " in in own cube window when you open it.",13,10
db 13,10
db " Other key functions :",13,10
db 13,10
db " INSERT - Opens the cube window (Client side).",13,10
db " HOME - Opens the cube. You must have your cursor",13,10
db " over the cube when you press the key.",13,10
db " PAGE UP - Drop to the ground the item you are",13,10
db " currently holding (When you pick it up).",13,10
db 13,10
db " This program has been made to do the cube exploit",13,10
db " easily and fast. The purpose is to help people ",13,10
db " figure out a duping method with this.",13,10
db " If you find one, tell me ;)",13,10
db 13,10
db " Check the readme.txt file for more information.",13,10
db 13,10
db " The original copy of this program can",13,10
db " always be found at http://onesided.cjb.net",0
aboutText db " Compatible with Diablo II/LoD v1.09d",13,10
db 13,10
db " Author : Arsenic",13,10
db " (a.k.a Artemis`Entreri)",13,10
db 13,10
db " Email : DumbassSk8er@hotmail.com",13,10
db 13,10
db " Site : http://onesided.cjb.net",0
;Icon
hIcon dd 0
;Memory Adresses To Patch
PATCH1ADDR equ 6fae139ch
CALL1ADDR equ 6facef84h
ROUT1ADDR equ 6fba12e0h
ROUT2ADDR equ 6fba1310h
ROUT3ADDR equ 6fba133eh
;------------------------------------------------------------
;Datas to be written
patch1 db 0ebh
call1 db 0e8h,57h,23h,0dh,00h
routine1 db 8bh,77h,08h,33h,0d2h,83h,0feh,2dh,75h,09h,60h,0e8h,0d0h,51h,0f4h,0ffh
db 61h,0ebh,0ah,83h,0feh,24h,75h,05h,0e8h,13h,00h,00h,00h,83h,0feh,21h
db 75h,05h,0e8h,37h,00h,00h,00h,0c3h
routine2 db 60h,0a1h,0b8h,0fbh,0bbh,6fh,85h,0c0h,74h,20h,8bh,50h,08h,8bh,2dh,0f8h
db 63h,0bch,6fh,55h,0e8h,89h,0d1h,0fbh,0ffh,8bh,0f8h,55h,0e8h,7bh,0d1h,0fbh
db 0ffh,50h,57h,0b1h,20h,0e8h,0e6h,0c0h,0f0h,0ffh,61h,0c3h
routine3 db 60h,0a1h,0f8h,63h,0bch,6fh,8bh,80h,84h,00h,00h,00h,8bh,40h,18h,85h
db 0c0h,74h,0ch,8bh,40h,08h,8bh,0d0h,0b1h,17h,0e8h,0f3h,0bfh,0f0h,0ffh,61h
db 0c3h
;------------------------------------------------------------
;Original Datas
patch1Old db 75h
call1Old db 8bh,77h,08h,33h,0d2h
;------------------------------------------------------------
errorPatching db 00h
.data?
hInstance HINSTANCE ?
processID dd ?
processHandle dd ?
.const
IDC_APPLY equ 3000
IDC_UNLOAD equ 3001
IDC_INFO equ 3003
IDC_ABOUT equ 3004
INFO_TEXT equ 5000
ABOUT_TEXT equ 4000
IDC_ABOUTOK equ 4001
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke WinMain, hInstance,NULL,NULL,SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hDlg:HWND
invoke LoadIcon,hInst,500 ; icon ID
mov hIcon, eax
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,DLGWINDOWEXTRA
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
push hIcon ; Put Icon on the Exe
pop wc.hIcon
push hIcon
pop wc.hIconSm
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateDialogParam,hInstance,ADDR DlgName,NULL,NULL,NULL
mov hDlg,eax
INVOKE ShowWindow, hDlg,SW_SHOWNORMAL
INVOKE UpdateWindow, hDlg
invoke GetDlgItem,hDlg,IDC_APPLY
invoke SetFocus,eax
.WHILE TRUE
INVOKE GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke IsDialogMessage, hDlg, ADDR msg
.if eax==FALSE
INVOKE TranslateMessage, ADDR msg
INVOKE DispatchMessage, ADDR msg
.endif
.ENDW
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
mov edx,wParam
shr edx,16
.IF dx==BN_CLICKED
.IF ax==IDC_APPLY
invoke ApplyProc,hWnd
.IF errorPatching==FALSE
invoke SetDlgItemText,hWnd,IDC_APPLY,addr appliedMsg
.ELSE
invoke SetDlgItemText,hWnd,IDC_APPLY,addr applyMsg
.ENDIF
.ELSEIF ax==IDC_UNLOAD
invoke UnloadProc,hWnd
invoke SetDlgItemText,hWnd,IDC_APPLY,addr applyMsg
.ELSEIF ax==IDC_INFO
invoke DialogBoxParam,hInstance,addr InfoDlgName,hWnd,addr InfoProc,NULL
.ELSEIF ax==IDC_ABOUT
invoke DialogBoxParam,hInstance,addr AboutDlgName,hWnd,addr AboutProc,NULL
.ENDIF
.ENDIF
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
ApplyProc proc hWnd:HWND
invoke GetHandleProc
.IF eax!=NULL
invoke SpyCheckProc,hWnd
.IF eax==NULL
invoke WriteProcessMemory, processHandle, PATCH1ADDR, addr patch1, sizeof patch1, NULL
test eax,eax
jz Error_Writing
invoke WriteProcessMemory, processHandle, CALL1ADDR, addr call1, sizeof call1, NULL
test eax,eax
jz Error_Writing
invoke WriteProcessMemory, processHandle, ROUT1ADDR, addr routine1, 40, NULL
test eax,eax
jz Error_Writing
invoke WriteProcessMemory, processHandle, ROUT2ADDR, addr routine2, 44, NULL
test eax,eax
jz Error_Writing
invoke WriteProcessMemory, processHandle, ROUT3ADDR, addr routine3, 33, NULL
test eax,eax
jz Error_Writing
;Patch successful
jmp Done
Error_Writing:
invoke MessageBox,hWnd,addr err_writing,addr err_cap,MB_ICONERROR
mov errorPatching,TRUE
Done:
invoke CloseHandle,processHandle ;Close the opened process
.ENDIF
.ENDIF
ret
ApplyProc endp
UnloadProc proc hWnd:HWND
invoke GetHandleProc
.IF eax!=NULL
invoke SpyCheckProc,hWnd
.IF eax==NULL
invoke WriteProcessMemory, processHandle, PATCH1ADDR, addr patch1Old, sizeof patch1Old, NULL
test eax,eax
jz Error_Writing
invoke WriteProcessMemory, processHandle, CALL1ADDR, addr call1Old, sizeof call1Old, NULL
test eax,eax
jz Error_Writing
jmp Done
Error_Writing:
invoke MessageBox,hWnd,addr err_writing,addr err_cap,MB_ICONERROR
Done:
invoke CloseHandle,processHandle ;Close the opened process
.ENDIF
.ENDIF
ret
UnloadProc endp
GetHandleProc proc
invoke FindWindow,NULL,addr GameName
.IF eax==NULL
invoke MessageBox,NULL,addr err_mustRun,addr err_cap,MB_ICONEXCLAMATION
mov errorPatching,TRUE
xor eax,eax
ret
.ENDIF
mov errorPatching,FALSE
invoke GetWindowThreadProcessId,eax,addr processID
invoke OpenProcess,PROCESS_ALL_ACCESS,NULL,processID
mov processHandle,eax
ret
GetHandleProc endp
SpyCheckProc proc handle:HWND
szText SpyName,"TRAINER SPY"
invoke FindWindow,NULL,addr SpyName
.IF eax!=NULL ;Spy exists
szText err_trainerSpy,"Close trainer spy... " ;Hide string
invoke MessageBox,handle,addr err_trainerSpy,addr err_cap,MB_ICONERROR
mov errorPatching,TRUE
push 1
pop eax
.ELSE
mov errorPatching,FALSE
.ENDIF
ret
SpyCheckProc endp
InfoProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_INITDIALOG
invoke GetDlgItem, hWnd,IDC_ABOUTOK
invoke SetFocus,eax
invoke SetDlgItemText,hWnd,INFO_TEXT,addr infoText
.ELSEIF uMsg==WM_CLOSE
invoke EndDialog,hWnd,NULL
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
mov edx,eax
shr edx,16
.IF dx==BN_CLICKED
.IF eax==IDC_ABOUTOK
invoke EndDialog,hWnd,NULL
.ENDIF
.ENDIF
.ELSE
mov eax,FALSE
ret
.ENDIF
mov eax,TRUE
ret
InfoProc endp
AboutProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_INITDIALOG
invoke GetDlgItem, hWnd,IDC_ABOUTOK
invoke SetFocus,eax
invoke SetDlgItemText,hWnd,ABOUT_TEXT,addr aboutText
.ELSEIF uMsg==WM_CLOSE
invoke EndDialog,hWnd,NULL
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
mov edx,eax
shr edx,16
.IF dx==BN_CLICKED
.IF eax==IDC_ABOUTOK
invoke EndDialog,hWnd,NULL
.ENDIF
.ENDIF
.ELSE
mov eax,FALSE
ret
.ENDIF
mov eax,TRUE
ret
AboutProc endp
end startLocateBy WindowName "Diablo II"
START "V1.09d" "Allow Cube In Cube"
;Written By Artemis`Entreri, a.k.a Arsenic
6fae139c 75 eb
END
start "v1.09d" "Cube Hack - v1.0"
;Press 'INSERT' to open the cube window.
;Press 'HOME' when cursor is over cube to open it.
;To get your cube back when it has disappeared from your inventory, press 'INSERT' to open
;window, place your cursor over the cube that is in the cube, press 'HOME', then move items
;in the cube or the cube itself.
;You will get booted out of the game if you try to move an item in the cube if you only opened
;the cube window with the 'INSERT' key.
6facef84 8b770833d2 e867230d00
6fba12f0 00000000000000000000000000000000 8b770833d283fe2d750960e8c051f4ff
6fba1300 0000000000000000000000000000 61eb0a83fe247505e803000000c3
6fba1310 00000000000000000000000000000000 60a1b8fbbb6f85c074208b50088b2df8
6fba1320 00000000000000000000000000000000 63bc6f55e889d1fbff8bf855e87bd1fb
6fba1330 000000000000000000000000 ff5057b120e8e6c0f0ff61c3
end Cube Exploit v1.1
This program will apply a patch into the Diablo II process memory, therefore you need to have
D2 running before applying. Hit Alt+Tab on your keyboard when you're in D2 to minimize it, then
run this program and apply the patch.
-----------------
What it does
-----------------
Allow you to put the cube inside the cube. When the cube window is opened, you can take the cube
from your inventory and put it in the cube window.
Other key functions :
INSERT - Opens the cube window (Client side).
HOME - Opens the cube. You must have your cursor over the cube when you press the key.
PAGE UP - Drop to the ground the item you are currently holding, meaning the one you just
picked up.
-----------------------------
My cube disappeared, WTF??
-----------------------------
To get your cube back, or any items that were in before you closed the window, do the
following :
1) Press INSERT to open the cube window client side.
2) From that point, DON'T pick up anything from the cube, else you will get booted from the
server and get a nice "Realms Down" message. You need to open the cube in the first place
before picking up or moving any items inside. Move your cursor over the cube that is in the
cube window, and press HOME. This will send the packet telling the server you opened the cube.
3) Pick up items in the cube window as you want :)
-------------------------------
Purpose of this whole thingy
-------------------------------
To do this exploit with ease and quickly ;)
Yet, what's the point of it? It does nothing interesting! Indeed, but we might find a way to
dupe with it. That's the whole idea.
If someone does, post your method at http://forums.cheatlist.com, http://forums.d2network.com,
or at Nuttzy's forum at www.blizzhacker.com.
You can always tell me in private how to do it too :)
I might update the program and add some other features if needed, so check out my site to see
the latest developments.
--------------
Credits
--------------
- Myself, for the nice program and memory patch :)
- Opticum, as his name goes by on Nuttzy's forum, who has originally found this exploit and made
a thread about it saying that a dupe might be possible, therefore gave me the idea to make
this program.
--------------------------------------
~ Arsenic a.k.a Artemis`Entreri
E-mails : DumbassSk8er@hotmail.com
arsenic@rootshell.be
Web page : http://onesided.cjb.net
www.onesided.da.ru (Mirror)TECHNOLOGIES
- x86 Assembly
- Packet Injection
- Reverse Engineering