Board logo

标题: [原创] d2hackmap在城内强化的方法 [打印本页]

作者: whiterabbit    时间: 2024-2-18 17:18     标题: d2hackmap在城内强化的方法

最近发现有人能在城内强化玩家,上网研究了很久,终于找到方法了。
首先在d2hackmap.cfg中加一行打开自动强化,这样在城外就能自动强化了
Auto Enchant Toggle: 1, -1
而在城内强化,在d2hackmap的代码中是禁止的,上网终于找到了一份d2hackmap的代码可以参考,但编译出来和anhei2上下载的大小不太一样。代码如下,可以看出代码首先判断是不是在城内,如果是就退出了。而且代码中有明显的bug,那就是如果玩家或召唤物编号超过1000,整个程序立刻崩溃。如果你的强化法师进入一个玩了20分钟的游戏,里面有几个新手死灵法师,那你的强化法师一进入立刻窗口就崩溃了。
void AutoEnchantLoop( UnitAny *pUnit ){
        static int delays = 0 ;//延时
        static int unitCount[2][1000] = {0,};  //1K
        if(fPlayerInTown){
                //出城后,等会开始
                delays = 1000;
                return;
        }
        if ( delays >0 ) {
                delays -- ;
                return;
        }
        DWORD dwUnitId = pUnit->dwUnitId ;
        if ( pUnit->dwUnitType==UNITNO_PLAYER && dwUnitId == dwPlayerId) return; //不给自己强化
        if ( PLAYER->pSkill->pRightSkill->pSkillInfo->wSkillId !=52 ) return;//需要右键开启强化
        if ( pUnit->dwUnitType==UNITNO_MONSTER ){
                dwUnitId = D2GetMonsterOwner(pUnit->dwUnitId);
                if (dwUnitId == (DWORD)-1)return; //非玩家随从
        }
        if ( D2CheckUnitState(pUnit, 16) )return; //已强化
        if ( unitCount[pUnit->dwUnitType][pUnit->dwUnitId] >0 ) {
                //没强化状态,但计时未结束,不做强化动作
                unitCount[pUnit->dwUnitType][pUnit->dwUnitId] = unitCount[pUnit->dwUnitType][pUnit->dwUnitId] -1;
                return;
        }
        if ( TestPvpFlag( dwPlayerId, dwUnitId )>=2 ){
                //只能给盟友
                unitCount[pUnit->dwUnitType][pUnit->dwUnitId] = 2000; //开始计时
                delays = 800 ; //在下次发送前,全局计时
                BYTE castTP1[9] = {0x0D};
                *(DWORD*)&castTP1[1] = pUnit->dwUnitType;
                *(DWORD*)&castTP1[5] = pUnit->dwUnitId;
                D2SendPacket(sizeof(castTP1), 0, castTP1);               
        }
        return;
}
在anhei2上下载的113map的d2hackmap.dll内存中AutoEnchantLoop对应代码如下:
AutoEnchantLoop
d2hackmap.dll+11AB0 - 55                    - push ebp
d2hackmap.dll+11AB1 - 8B EC                 - mov ebp,esp
d2hackmap.dll+11AB3 - 83 EC 14              - sub esp,14
d2hackmap.dll+11AB6 - A1 40808A01           - mov eax,[d2hackmap.dll+28040]
d2hackmap.dll+11ABB - 33 C5                 - xor eax,ebp
d2hackmap.dll+11ABD - 89 45 F8              - mov [ebp-08],eax
d2hackmap.dll+11AC0 - 83 3D FCBB8A01 00     - cmp dword ptr [d2hackmap.dll+2BBFC],00 { (1),0 }
d2hackmap.dll+11AC7 - 74 0F                 - je d2hackmap.dll+11AD8
可以看出程序是在d2hackmap.dll+11AC0判断是不是在城内的,只要改两个字节,直接跳到11AD8就可以在城内强化了。
d2hackmap.dll+11AC0 - EB 16                 - jmp d2hackmap.dll+11AD8
这行代码在dllhackmap.dll文件的位置是0x10ec0, 这里的dllhackmap.dll必须是anhei2网站上下载的那个大小为193536字节的,如果是别的地方下载的可能位置不一样,需要自己找。
下面这段C代码可以自动修改d2hackmap.dll打开城内强化,但是dwUnitId的bug没有改正,在新建的游戏里用没有问题,时间久了强化法师就会退出,那就再建个新游戏吧,或者自己把后面的汇编代码看一下打上补丁。
要运行C代码可以下载tcc,一共只有4MB
http://download.savannah.gnu.org/releases/tinycc/
http://download.savannah.gnu.org ... .9.27-win32-bin.zip
http://download.savannah.gnu.org ... full-for-0.9.27.zip
使用类似下面的命令行来运行C程序
d:\tcc\tcc\tcc.exe -luser32 -ID:/tcc/winapi-full-for-0.9.27/include/winapi -run d:\git\diablo2\patch_d2hackmap.c
---------patch_d2hackmap.c-------------
#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include <assert.h>
char *load(char *path,int *psize) {
        FILE *fp=fopen(path,"rb");
        if (!fp) {printf("Can't open %s\n",path);assert(0);}
        fseek(fp,0,2);int size=ftell(fp);*psize=size;
        char *p=malloc(size+1);p[size]=0;fseek(fp,0,0);
        int n=fread(p,1,size,fp);assert(n==size);fclose(fp);
        return p;
}
void save(char *path,char *buf,int size) {
        FILE *fp=fopen(path,"wb+");assert(fp);
        int n=fwrite(buf,1,size,fp);assert(n==size);fclose(fp);
}
int check_code(unsigned char *code,int off,char *ptn,int n) {
        for (int i=0;i<n;i++) {
                unsigned char c=ptn;if (c==0xFF) continue;
               if (code[off+i]!=c) return 0;
        }
        return 1;
}
void auto_enchant_patch() {
//d2hackmap.dll+11AC0 - 83 3D FCBB8A01 00     - cmp dword ptr [d2hackmap.dll+2BBFC],00 { (1),0 }
//d2hackmap.dll+11AC7 - 74 0F                 - je d2hackmap.dll+11AD8
//d2hackmap.dll+11AC9 - C7 05 F08BAA01 E8030000 - mov [d2hackmap.dll+228BF0],000003E8 { (0),1000 }
        unsigned char org[19]={0x83,0x3d,0xff,0xff,0xff,0xFF,0,
                0x74,0xF,
                0xC7,0x05,0xFF,0xFF,0xFF,0xFF,0xE8,3,0,0};
        unsigned char patch[2]={0xeb,0x16};
        char *path="D:/game/diablo2/113map/d2hackmap.dll";
        char *outpath="D:/game/diablo2/113map/d2hackmap_qh.dll";
        int size;char *code=load(path,&size);
        int offset=0x10ec0;
        printf("Load %s size %d\n",path,size);
        if (!check_code(code,offset,org,19)) {
                printf("ERROR: dll mismatch\n");
                return;
        }
        printf("Check OK\n");
        memcpy(code+offset,patch,2);
        printf("save to %s\n",outpath);
        save(outpath,code,size);
        return;
}
int main( void ) {
        auto_enchant_patch();return 0;
}
另外还有一个更重要的程序,那就是以窗口模式启动暗黑2后去掉窗口标题和边框并且最大化,效果和全屏一样,但是可以输入中文,而且可以两个窗口快速切换,适合双开。在战网上最郁闷的就是遇到有人用玄文了,遇到基本马上就退,而且几天内也不想加入公开的游戏了。我也看过天书,知道使用玄文九成可能是故意不让人看明白。但有人说我不会英文,又非要用全屏模式启动,输入不了中文,而且我一定要不停发大段的消息。所以了,下面的程序可以达到全屏并且输入中文的效果,如果还不使用通用语言的话,那我也肯定不看。当然了,估计没多少人会用,因为用玄文是暗黑2的惯例,网上关于暗黑2的中文贴子新人估计一句也看不懂,比如说dykb指的是地狱Kill Baal,前面一半是拼音,后面一半是英文,这已经是很高级别的玄学了。再比如说anhei2网站一直置顶的贴子《法师不能进房间的请尽快覆盖 》,我就一直不知道是什么意思,直到现在我还经常看到有法师不停进入和离开游戏,估计是没装验证码补丁,我以前也要连续进几十次,一直显示“加入游戏失败”,后来有老玩家告诉我建立游戏叫开房,加入游戏叫进房,我才知道是怎么回事,为什么不让法师进,刺客和亚马逊就可以。
---------fullscreen.c-------------
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include <assert.h>
char *dir="D:\\game\\diablo2";
char *cmdline="D:\\game\\diablo2\\D2Loader.exe -locale chi -lq -pdir 113map -direct -skiptobnet -w -title %s";
int main(int argc,char *argv[]) {
        char title[256];
        char cmd[256];
        for (int i=1;i<1000;i++) {
                snprintf(title,256,"D2_%d",i);
                HWND hwnd=FindWindowA(NULL,title);
                if (!hwnd) break;
        }
        snprintf(cmd,256,cmdline,title);
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory( &si, sizeof(si) );
        si.cb = sizeof(si);
        ZeroMemory( &pi, sizeof(pi) );
        printf("%s\n",cmd);
        if( !CreateProcess( NULL,   // No module name (use command line)
                        cmd,        // Command line
                        NULL,           // Process handle not inheritable
                        NULL,           // Thread handle not inheritable
                        FALSE,          // Set handle inheritance to FALSE
                        0,              // No creation flags
                        NULL,           // Use parent's environment block
                        dir,           // Use parent's starting directory
                        &si,            // Pointer to STARTUPINFO structure
                        &pi )           // Pointer to PROCESS_INFORMATION structure
        )
        {
                        printf( "CreateProcess failed.\n");
                        return;
        }
        for (int i=0;i<20;i++) {
                HWND hwnd=FindWindowA(NULL,title);
                if (hwnd) {
                        int style=GetWindowLongA (hwnd,GWL_STYLE);
                        if (style&WS_CAPTION) {
                                style=style&(~WS_CAPTION);
                                SetWindowLongA(hwnd,GWL_STYLE,style);
                        }
                        ShowWindow(hwnd,SW_SHOWMAXIMIZED);
                        break;
                }
                Sleep(500);
        }
        return 0;
}
作者: bsgxxx    时间: 2024-2-18 17:45


作者: 7582645    时间: 2024-2-18 18:18

程序猿大佬
作者: youxiarock    时间: 2024-2-18 18:37

这, 现在玩游戏需求这么高了吗
作者: acc888wl    时间: 2024-2-18 20:51     标题: 我眼球都变大一千倍了

我在玩游戏还是游戏在玩我!!!!
作者: 天天打渔    时间: 2024-2-18 23:06

能自己参与设定的 才是可玩的
作者: h82118    时间: 2024-2-19 12:19

下面的代码太专业了
作者: foxchn111    时间: 2024-2-20 18:16

牛,就一个字




欢迎光临 anhei3战网 (http://test.anhei2.com/) Powered by Discuz! 6.0.0