吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 76809|回复: 256
收起左侧

[漏洞分析] 魔兽争霸-领取收费道具漏洞

    [复制链接]
你坏 发表于 2018-11-30 17:14
本帖最后由 你坏 于 2019-5-2 19:52 编辑

案例:官方平台
案例.png
商城:收费道具
商城.png
测试:自定义房间(龙珠)
测试.png
大量:伪人民币玩家
最后的疯狂.png

提取地图脚本:
解压脚本.png


锁定漏洞位置:
[Lua] 纯文本查看 复制代码
function Trig_GFFunc001A takes nothing returns nothing
if GetEnumPlayer()!=Player(10) and GetEnumPlayer()!=Player(11) and GetEnumPlayer()!=Player(PLAYER_NEUTRAL_AGGRESSIVE) then
if S2I(DzAPI_Map_GetServerValue(GetEnumPlayer(),"B"))==0 and StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("月牙兲冲~-") then
call DzAPI_Map_SaveServerValue(GetEnumPlayer(),"B","S2I(1)")
call DzAPI_Map_SaveServerValue(GetEnumPlayer(),"J",I2S(S2I(DzAPI_Map_GetServerValue(GetEnumPlayer(),"J"))+300))
else
endif
if DzAPI_Map_GetMapLevel(GetEnumPlayer())<=10 and S2I(DzAPI_Map_GetServerValue(GetEnumPlayer(),"G"))>=500 then
call DzAPI_Map_SaveServerValue(GetEnumPlayer(),"G","")
call DzAPI_Map_SaveServerValue(GetEnumPlayer(),"g","")
else
endif
if DzAPI_Map_GetMapLevel(GetEnumPlayer())<=10 and S2I(DzAPI_Map_GetServerValue(GetEnumPlayer(),"J"))>=500 then
call DzAPI_Map_SaveServerValue(GetEnumPlayer(),"J","")
call DzAPI_Map_SaveServerValue(GetEnumPlayer(),"j","")
else
endif
call SaveInteger(YDHT,GetHandleId(GetEnumPlayer()),$F034EC60,S2I(DzAPI_Map_GetServerValue(GetEnumPlayer(),"J")))
call SaveInteger(YDHT,GetHandleId(GetEnumPlayer()),$D634A9E,S2I(DzAPI_Map_GetServerValue(GetEnumPlayer(),"G")))
if DzAPI_Map_GetMapConfig("DZ")==GetPlayerName(GetEnumPlayer()) or DzAPI_Map_GetMapConfig("DZ2")==GetPlayerName(GetEnumPlayer()) or DzAPI_Map_GetMapConfig("DZ3")==GetPlayerName(GetEnumPlayer()) or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("雄霸天下147~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("虎牙丶小布叮雪糕~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("虎牙霸王枪~-") or HWK()==true then
call SaveInteger(YDHT,GetHandleId(GetEnumPlayer()),$18FC6F47,1)
set udg_TSSX_ZS[GetConvertedPlayerId(GetEnumPlayer())]=udg_TSSX_ZS[GetConvertedPlayerId(GetEnumPlayer())]+5.
else
endif
if DzAPI_Map_GetMapConfig("DZ")==GetPlayerName(GetEnumPlayer()) or DzAPI_Map_GetMapConfig("DZ2")==GetPlayerName(GetEnumPlayer()) or DzAPI_Map_GetMapConfig("DZ3")==GetPlayerName(GetEnumPlayer()) or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("雄霸天下147~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("虎牙丶小布叮雪糕~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("虎牙霸王枪~-") or THHWK()==true then
call AddPlayerTechResearched(GetEnumPlayer(),$5230314F,1)
set udg_TSSX_ZS[GetConvertedPlayerId(GetEnumPlayer())]=udg_TSSX_ZS[GetConvertedPlayerId(GetEnumPlayer())]+10.
else
endif
if DzAPI_Map_GetMapConfig("DZ")==GetPlayerName(GetEnumPlayer()) or DzAPI_Map_GetMapConfig("DZ2")==GetPlayerName(GetEnumPlayer()) or DzAPI_Map_GetMapConfig("DZ3")==GetPlayerName(GetEnumPlayer()) or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("强子阿~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("琥珀丶川~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("雄霸天下147~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("虎牙丶小布叮雪糕~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("虎牙霸王枪~-") or ZZY()==true then
call AddPlayerTechResearched(GetEnumPlayer(),$52303148,1)
set udg_TSSX_ZS[GetConvertedPlayerId(GetEnumPlayer())]=udg_TSSX_ZS[GetConvertedPlayerId(GetEnumPlayer())]+5.
call SaveReal(YDHT,GetHandleId(udg_d[GetConvertedPlayerId(GetEnumPlayer())]),$6BC38F96,udg_TSSX_ZS[GetConvertedPlayerId(GetEnumPlayer())])
else
endif
if DzAPI_Map_GetMapConfig("DZ")==GetPlayerName(GetEnumPlayer()) or DzAPI_Map_GetMapConfig("DZ2")==GetPlayerName(GetEnumPlayer()) or DzAPI_Map_GetMapConfig("DZ3")==GetPlayerName(GetEnumPlayer()) or DzAPI_Map_GetMapConfig("DZ4")==GetPlayerName(GetEnumPlayer()) or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("强子阿~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("雄霸天下147~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("虎牙丶小布叮雪糕~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("虎牙霸王枪~-") or WQZZY()==true then
call AddPlayerTechResearched(GetEnumPlayer(),$52303149,1)
set udg_TSSX_ZS[GetConvertedPlayerId(GetEnumPlayer())]=udg_TSSX_ZS[GetConvertedPlayerId(GetEnumPlayer())]+10.
call SaveReal(YDHT,GetHandleId(udg_d[GetConvertedPlayerId(GetEnumPlayer())]),$6BC38F96,udg_TSSX_ZS[GetConvertedPlayerId(GetEnumPlayer())])
else
endif
if DzAPI_Map_GetMapConfig("DZ")==GetPlayerName(GetEnumPlayer()) or DzAPI_Map_GetMapConfig("DZ2")==GetPlayerName(GetEnumPlayer()) or DzAPI_Map_GetMapConfig("DZ3")==GetPlayerName(GetEnumPlayer()) or DzAPI_Map_GetMapConfig("DZ4")==GetPlayerName(GetEnumPlayer()) or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("雄霸天下147~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("虎牙丶小布叮雪糕~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("虎牙霸王枪~-") or BJT()==true then
call AddPlayerTechResearched(GetEnumPlayer(),$5230314E,1)
else
endif
if DzAPI_Map_GetMapLevel(GetEnumPlayer())>=7 then
call AddPlayerTechResearched(GetEnumPlayer(),$5230314B,1)
else
endif
if DzAPI_Map_GetStoredInteger(GetEnumPlayer(),"N1")==1 or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("超级赛亚神十阶~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("丶盛盛盛盛盛~-") or DzAPI_Map_GetMapConfig("HD")=="开启" then
call AddPlayerTechResearched(GetEnumPlayer(),$52303146,1)
call SaveInteger(YDHT,GetHandleId(GetEnumPlayer()),$27DFC423,1)
else
endif
if DzAPI_Map_GetStoredInteger(GetEnumPlayer(),"N2")==1 or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("超级赛亚神十阶~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("丶盛盛盛盛盛~-") or DzAPI_Map_GetMapConfig("HD")=="开启" then
call AddPlayerTechResearched(GetEnumPlayer(),$52303142,1)
call SaveInteger(YDHT,GetHandleId(GetEnumPlayer()),$5D6F8057,1)
else
endif
if DzAPI_Map_GetStoredInteger(GetEnumPlayer(),"N3")==1 or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("超级赛亚神十阶~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("丶盛盛盛盛盛~-") or DzAPI_Map_GetMapConfig("HD")=="开启" then
call AddPlayerTechResearched(GetEnumPlayer(),$52303143,1)
call SaveInteger(YDHT,GetHandleId(GetEnumPlayer()),$C100A2BF,1)
else
endif
if DzAPI_Map_GetStoredInteger(GetEnumPlayer(),"N4")==1 or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("超级赛亚神十阶~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("丶盛盛盛盛盛~-") or DzAPI_Map_GetMapConfig("HD")=="开启" then
call AddPlayerTechResearched(GetEnumPlayer(),$52303144,1)
call SaveInteger(YDHT,GetHandleId(GetEnumPlayer()),$5A3EEF8D,1)
else
endif
if DzAPI_Map_GetStoredInteger(GetEnumPlayer(),"N5")==1 or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("超级赛亚神十阶~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("小兔兔丶々~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("Canrry。~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("丶盛盛盛盛盛~-") or DzAPI_Map_GetMapConfig("HD")=="开启" then
call AddPlayerTechResearched(GetEnumPlayer(),$52303145,1)
call SaveInteger(YDHT,GetHandleId(GetEnumPlayer()),$6C7E2719,1)
else
endif
if DzAPI_Map_GetStoredInteger(GetEnumPlayer(),"N6")==1 or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("超级赛亚神十阶~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("丶盛盛盛盛盛~-") or DzAPI_Map_GetMapConfig("HD")=="开启" then
call AddPlayerTechResearched(GetEnumPlayer(),$5230314A,1)
call SaveInteger(YDHT,GetHandleId(GetEnumPlayer()),$2F80B4C6,1)
else
endif
if DzAPI_Map_GetStoredInteger(GetEnumPlayer(),"N7")==1 or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("超级赛亚神十阶~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("丶盛盛盛盛盛~-") or DzAPI_Map_GetMapConfig("HD")=="开启" then
call SaveInteger(YDHT,GetHandleId(GetEnumPlayer()),$2FD71D4B,1)
else
endif
if DzAPI_Map_GetStoredInteger(GetEnumPlayer(),"N8")==1 or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("超级赛亚神十阶~-") or StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("丶盛盛盛盛盛~-") then
call SaveInteger(YDHT,GetHandleId(GetEnumPlayer()),$C93D1D12,1)
else
endif
else
endif
endfunction


锁定关键代码:
StringHash(GetPlayerName(GetEnumPlayer())+"~-")==StringHash("作者情殇~-")

分析漏洞代码
1.这个代码位于条件判断语句,条件成立就可获得收费道具的使用权
2.条件是哈希值和哈希值比较:
左侧计算的哈希值是(获取玩家名称+固定字符串)
右侧计算的哈希值是个固定字符串(拥有使用权的玩家)
3.为什么可以利用(同一个哈希值,可能对应N个玩家名称),
4.怎么利用
   1.生成随机名称(如果名称里面有字母,必须是大写),然后和固定字符串拼接
   2.计算拼接字符串的哈希值
   3.计算哈希值(拥有使用权的玩家)
   4.两个哈希值比较,如果相同,输出:生成的随机名称
   5.注册游戏账号,玩家名称输入:生成的随机名称
   6.然后就有了对应地图的赞助使用权

批量生成名称:
[Asm] 纯文本查看 复制代码
#include <Windows.h>
#include <cstdint>
#include <stdio.h>

//获取字符串的哈希值,核心
//参数一:字符串指针
//参数二:字符串长度
//参数三:填0就行
//返回值:返回字符串的哈希值
int __fastcall GetStringHash(unsigned __int8 *a1, unsigned int a2, int a3)
{
        unsigned int v3; // eax
        unsigned __int8 *v4; // edx
        int v5; // ecx
        unsigned int v6; // esi
        int v7; // ebx
        int v8; // edi
        int v9; // esi
        unsigned int v10; // edi
        int v11; // eax
        int v12; // ecx
        int v13; // ebx
        unsigned int v14; // esi
        unsigned int v15; // edi
        int v16; // ebx
        unsigned int v17; // esi
        unsigned int v18; // edi
        bool v19; // zf
        unsigned int v20; // edi
        int v21; // ebx
        unsigned int v22; // esi
        unsigned int v23; // edi
        int v24; // ebx
        unsigned int v25; // esi
        unsigned int v26; // edi
        int v27; // ebx
        unsigned int v29; // [esp+10h] [ebp-8h]
        unsigned int v30; // [esp+14h] [ebp-4h]
        int v31; // [esp+20h] [ebp+8h]

        v3 = a2;
        v4 = a1;
        v29 = v3;
        v5 = v3;
        v30 = v3;
        v6 = -1640531527;
        v7 = -1640531527;
        v8 = a3;
        if (v3 >= 0xC)
        {
                v31 = v3 / 0xC;
                do
                {
                        v9 = ((v4[5] + ((v4[6] + (v4[7] << 8)) << 8)) << 8) + v4[4] + v6;
                        v10 = ((v4[9] + ((v4[10] + (v4[11] << 8)) << 8)) << 8) + v4[8] + v8;
                        v11 = *v4;
                        v12 = (v4[1] + ((v4[2] + (v4[3] << 8)) << 8)) << 8;
                        v4 += 12;
                        v13 = (v10 >> 13) ^ (v11 + v12 - v10 - v9 + v7);
                        v14 = (v13 << 8) ^ (v9 - v10 - v13);
                        v15 = (v14 >> 13) ^ (v10 - v14 - v13);
                        v16 = (v15 >> 12) ^ (v13 - v15 - v14);
                        v17 = (v16 << 16) ^ (v14 - v15 - v16);
                        v18 = (v17 >> 5) ^ (v15 - v17 - v16);
                        v7 = (v18 >> 3) ^ (v16 - v18 - v17);
                        v6 = (v7 << 10) ^ (v17 - v18 - v7);
                        v8 = (v6 >> 15) ^ (v18 - v6 - v7);
                        v5 = v30 - 12;
                        v19 = v31-- == 1;
                        v30 -= 12;
                } while (!v19);
                v3 = v29;
        }
        v20 = v3 + v8;
        switch (v5)
        {
        case 1:
                goto LABEL_16;
        case 2:
                goto LABEL_15;
        case 3:
                goto LABEL_14;
        case 4:
                goto LABEL_13;
        case 5:
                goto LABEL_12;
        case 6:
                goto LABEL_11;
        case 7:
                goto LABEL_10;
        case 8:
                goto LABEL_9;
        case 9:
                goto LABEL_8;
        case 10:
                goto LABEL_7;
        case 11:
                v20 += v4[10] << 24;
        LABEL_7:
                v20 += v4[9] << 16;
        LABEL_8:
                v20 += v4[8] << 8;
        LABEL_9:
                v6 += v4[7] << 24;
        LABEL_10:
                v6 += v4[6] << 16;
        LABEL_11:
                v6 += v4[5] << 8;
        LABEL_12:
                v6 += v4[4];
        LABEL_13:
                v7 += v4[3] << 24;
        LABEL_14:
                v7 += v4[2] << 16;
        LABEL_15:
                v7 += v4[1] << 8;
        LABEL_16:
                v7 += *v4;
                break;
        default:
                break;
        }
        v21 = (v20 >> 13) ^ (v7 - v20 - v6);
        v22 = (v21 << 8) ^ (v6 - v20 - v21);
        v23 = (v22 >> 13) ^ (v20 - v22 - v21);
        v24 = (v23 >> 12) ^ (v21 - v23 - v22);
        v25 = (v24 << 16) ^ (v22 - v23 - v24);
        v26 = (v25 >> 5) ^ (v23 - v25 - v24);
        v27 = (v26 >> 3) ^ (v24 - v26 - v25);
        return (((v27 << 10) ^ (v25 - v26 - v27)) >> 15) ^ (v26 - ((v27 << 10) ^ (v25 - v26 - v27)) - v27);
}

//获取字符串的哈希值,包装
//参数一:字符串指针
//返回值:返回字符串的哈希值
int StringHash(char* pSting)
{
        return GetStringHash((unsigned __int8 *)pSting, StringLength(pSting), 0);
}

//字符串编码转换
char* Unicode2Utf8(wchar_t* pStr, int length)
{
        int u8Len = WideCharToMultiByte(CP_UTF8, NULL, pStr, length, NULL, 0, NULL, NULL);
        char* u8Str = new char[u8Len + 1];
        u8Str[u8Len] = '\0';
        WideCharToMultiByte(CP_UTF8, NULL, pStr, length, u8Str, u8Len, NULL, NULL);
        return u8Str;
}

int main()
{

        //拥有使用权的玩家
        WCHAR PlayerName[] = L"作者情殇~-";
        //计算玩家的哈希值
        int SH= StringHash(Unicode2Utf8(PlayerName, lstrlen(PlayerName)));
        //剩余代码自行完善
        ......
}


说明:
龙珠新版本已经和谐了此漏洞,有人卖ID,被作者知道了
漏洞不通用,具体要看地图的脚本里面有没有这种代码
网易的收费道具,代表了联机作弊的开始,此贴算是告一段落了

地图:
1.测试漏洞用,提供的地图是还没有和谐的版本
2.原版要去平台自定义房间建图
3.破解版不限制游戏平台,需要下载大地图补丁
4.这里提供我生成的玩家名称:RMHFOZDY
5.网易平台此名称可能被占用,可以单机用破解版来测试
链接: https://pan.baidu.com/s/1GDeYADbgvrcd7B-tlKyFbA 提取码: 8zcv




2019.3.25
玄辰界(未知)
洪荒浩劫(未知)

2019.1.22
破晓苍穹(已和谐)

2018.12.8
盗墓世界(未知),
神世灵者(已和谐)
梵天血狱(已和谐)
龙珠超2(已和谐),
煞魔之道(未知),
鬼点灯之寻龙诀(未知)

2018.1.6
龙脉(没测试,很早之前只大概看了一下)
弓箭手小生存(老图,无意间看到的,获取玩家名称计算哈希值,没看有什么用)
杀戮修神传(这个是获取存档值,计算存档值的哈希值,然后对比,需要存档工具设置存档)

免费评分

参与人数 42吾爱币 +40 热心值 +39 收起 理由
tancai941107 + 1 + 1 热心回复!
lnnny + 1 + 1 用心讨论,共获提升!
尘云奈 + 1 + 1 热心回复!
幸运Elancer + 1 + 1 用心讨论,共获提升!
萨半岛 + 1 + 1 热心回复!
df961108 + 1 + 1 动漫竞技之争和动漫终焉之战有这个漏洞吗
老头 + 1 + 1 老哥能给个lua或者变量的源码吗
夜行的小丑 + 1 谢谢@Thanks!
昆局水段 + 1 谢谢@Thanks!
q114271744 + 1 + 1 膜拜大佬
空不了 + 1 + 1 我很赞同!
xuexijinbu + 1 + 1 这些图其实就是个换皮游戏,基本上人物的技能装备都是类似,玩这图的人就是.
Wjr7god + 1 鼓励转贴优秀软件安全工具和文档!
茫侠 + 1 + 1 不明嚼栗!
Baslilon + 1 + 1 大佬 请问随机名称如何生成
notpasser + 1 + 1 我很赞同!
chang1582 + 1 + 1 谢谢@Thanks!
dongwuai + 1 + 1 我很赞同!
Lilcat + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lf2640515787 + 1 + 1 我很赞同!
Rossoneri_Sam + 1 + 1 谢谢@Thanks!
丶蜥蜴君 + 1 + 1 用心讨论,共获提升!
Mate丶 + 1 + 1 用心讨论,共获提升!
南觅倾城 + 1 谢谢@Thanks!
fatedivine + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
shajiaqin + 1 我很赞同!
暮色忘我 + 1 + 1 用心讨论,共获提升!
kousi007 + 1 + 1 能给个名称吗?生成器不会写
ws695057382 + 1 + 1 真是什么东西都被盗走卖掉
草月花舍 + 1 + 1 谢谢@Thanks!
笑哈哈123 + 1 + 1 那位朋友分享下已注册的测试帐号?试试新游
wangkai558 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
cappuccino + 1 + 1 谢谢@Thanks!
44018723 + 1 + 1 用心讨论,共获提升!
yAYa + 3 + 1 热心回复!
张老大爷 + 1 谢谢@Thanks!
jackliqiao + 1 + 1 我很赞同!
xiaokeke2014 + 1 我很赞同!
xans + 1 + 1 只能自定义么 怎么验证
五道杠小学生 + 1 + 1 谢谢@Thanks!
xiaolei7172 + 1 + 1 多来点教程,很有用。
youruhe + 1 + 1 不明觉厉! 小白坐等破解图!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

yaaisinile 发表于 2018-12-4 10:31
String2Hash源码


[C++] 纯文本查看 复制代码
#define STRING2HASH_EXPORTS
#include "String2Hash.h"

// String2Hash.cpp: 定义 DLL 应用程序的导出函数。
//
// ConsoleApplication1.cpp: 定义控制台应用程序的入口点。
//
#include "windows.h"
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <ctype.h>
#include <string.h>
#include <string>
#include <iostream>  

using namespace std;

uint32_t __stdcall StringHash(const char *str);




#define STRING_TO_LONG(s) (*((s) + 0) + ((*((s) + 1) + ((*((s) + 2) + (*((s) + 3) << 8)) << 8)) << 8))

#define T1(A, B, C)                  \
	(A) = ((C)>>13)^((A)-(B)-(C)); \
	(B) = ((A)<< 8)^((B)-(C)-(A)); \
	(C) = ((B)>>13)^((C)-(A)-(B)); \
	(A) = ((C)>>12)^((A)-(B)-(C)); \
	(B) = ((A)<<16)^((B)-(C)-(A)); \
	(C) = ((B)>> 5)^((C)-(A)-(B)); \
	(A) = ((C)>> 3)^((A)-(B)-(C)); \
	(B) = ((A)<<10)^((B)-(C)-(A)); \
	(C) = ((B)>>15)^((C)-(A)-(B)); \

#define T2(A, B, C)                  \
	(C) = ((C)^((B)>>15))+(B)+(A); \
	(B) = ((B)^((A)<<10))+(A)+(C); \
	(A) = ((A)^((C)>> 3))+(C)+(B); \
	(C) = ((C)^((B)>> 5))+(B)+(A); \
	(B) = ((B)^((A)<<16))+(A)+(C); \
	(A) = ((A)^((C)>>12))+(C)+(B); \
	(C) = ((C)^((B)>>13))+(B)+(A); \
	(B) = ((B)^((A)<< 8))+(A)+(C); \
	(A) = ((A)^((C)>>13))+(C)+(B); \

uint32_t StringHashImpl(unsigned char *str, size_t size)
{
	size_t len = size;

	uint32_t A = 0x9E3779B9;
	uint32_t B = 0x9E3779B9;
	uint32_t C = 0;

	while (len >= 12)
	{
		A += STRING_TO_LONG(str + 0);
		B += STRING_TO_LONG(str + 4);
		C += STRING_TO_LONG(str + 8);

		T1(A, B, C);

		str += 12;
		len -= 12;
	}

	C = C + size;

	switch (len)
	{
	case 11: C += str[10] << 24;
	case 10: C += str[9] << 16;
	case  9: C += str[8] << 8;
	case  8: B += str[7] << 24;
	case  7: B += str[6] << 16;
	case  6: B += str[5] << 8;
	case  5: B += str[4];
	case  4: A += str[3] << 24;
	case  3: A += str[2] << 16;
	case  2: A += str[1] << 8;
	case  1: A += str[0];
		break;
	default:
		break;
	}

	T1(A, B, C);

	return C;
}
#undef T1
#undef T2
#undef STRING_TO_LONG

uint32_t __stdcall StringHash(const char *str)
{
	char buffer[0x400];
	size_t len = 0;

	while (str[len])
	{
		if (len >= 0x3FF) break;
		buffer[len] = str[len] == '/' ? '\\' : toupper(str[len]);
		len++;
	}

	return StringHashImpl((unsigned char*)buffer, len);
}
char* G2U(const char* gb2312)
{
	int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);
	MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);
	len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* str = new char[len + 1];
	memset(str, 0, len + 1);
	WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
	if (wstr) delete[] wstr;
	return str;
}
~零度 发表于 2018-12-1 10:28
本帖最后由 ~零度 于 2018-12-1 10:32 编辑

魔兽争霸我一般都玩免费的地图,都是单机版的,一个人玩。


顺便一提,竟然在C程序里写goto,我之前这样被老师嘲讽过。数字对应到Label可以用宏定义啊,#define LABEL_7 10,然后switch里面用case LABEL_7就行了,再调整一下case的顺序就行了。

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
黑龍 + 1 + 1 谢谢@Thanks!

查看全部评分

zghqhq 发表于 2018-11-30 17:48
lingyv 发表于 2018-11-30 17:48
感谢分享谢谢
wk4funny 发表于 2018-11-30 17:49
这种事反应还是快
 楼主| 你坏 发表于 2018-11-30 17:56
wk4funny 发表于 2018-11-30 17:49
这种事反应还是快

主要是刷的人多,别人在卖
别人加群,私下拉人卖,在平台挂房
玩这个地图几天了,今天和谐了
heibai110 发表于 2018-11-30 18:05
谢谢分享!大神威武
大将军 发表于 2018-11-30 18:09
主要是这游戏实在老了。  
lvchuanya 发表于 2018-11-30 18:21
下载一下  看看效果
五道杠小学生 发表于 2018-11-30 18:56
所有地图都通用吗?大佬
懿轩 发表于 2018-11-30 18:59
只能自定义吧?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 14:07

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表