写入HP
// 这个分析到此为止,我们在修改血量时发现第一个是会变化的, 但是只是在任务传送的过程中会变化, 而且需要锁定血值,所以重点分析第一个
// 调试器附加这城后,一定要让恢复所有线程,否则会检测到调试器, 应该是有线程在做中断检测或者是判断时钟没有执行
// x64dbg分析
LineageR.exe+20E3EB0
00007FF6CF2A3EB0 | 48:895C24 10 | mov qword ptr ss:[rsp+0x10],rbx |
00007FF6CF2A3EB5 | 48:896C24 18 | mov qword ptr ss:[rsp+0x18],rbp | [rsp+18]:&L"禀栩翺"
00007FF6CF2A3EBA | 48:897424 20 | mov qword ptr ss:[rsp+0x20],rsi |
00007FF6CF2A3EBF | 57 | push rdi |
00007FF6CF2A3EC0 | 48:83EC 40 | sub rsp,0x40 |
00007FF6CF2A3EC4 | 8B81 60010000 | mov eax,dword ptr ds:[rcx+0x160] | 这里没有得到过4
00007FF6CF2A3ECA | 48:8D99 58010000 | lea rbx,qword ptr ds:[rcx+0x158] | rbx = rcx + 0x158, rcx = 288BDAEE740
00007FF6CF2A3ED1 | 33ED | xor ebp,ebp |
00007FF6CF2A3ED3 | 48:63FA | movsxd rdi,edx | 取参数2
00007FF6CF2A3ED6 | 49:8BF0 | mov rsi,r8 |
00007FF6CF2A3ED9 | 3B81 8C010000 | cmp eax,dword ptr ds:[rcx+0x18C] |
00007FF6CF2A3EDF | 74 4C | je lineager.7FF6CF2A3F2D | 这里跳走了
00007FF6CF2A3EE1 | 48:8B4B 40 | mov rcx,qword ptr ds:[rbx+0x40] |
00007FF6CF2A3EE5 | 4C:8D53 38 | lea r10,qword ptr ds:[rbx+0x38] |
00007FF6CF2A3EE9 | 4C:634B 48 | movsxd r9,dword ptr ds:[rbx+0x48] |
00007FF6CF2A3EED | 49:FFC9 | dec r9 |
00007FF6CF2A3EF0 | 4C:23CF | and r9,rdi | r9 = 04
00007FF6CF2A3EF3 | 48:85C9 | test rcx,rcx |
00007FF6CF2A3EF6 | 4C:0F45D1 | cmovne r10,rcx |
00007FF6CF2A3EFA | 43:8B048A | mov eax,dword ptr ds:[r10+r9*4] |
00007FF6CF2A3EFE | 83F8 FF | cmp eax,0xFFFFFFFF | eax = 04时不执行这里
00007FF6CF2A3F01 | 74 2A | je lineager.7FF6CF2A3F2D |
00007FF6CF2A3F03 | 48:8B13 | mov rdx,qword ptr ds:[rbx] | 应该是来自于这里,rbx = 00000288BDAEE898
00007FF6CF2A3F06 | 6666:0F1F8400 00000000 | nop word ptr ds:[rax+rax],ax |
00007FF6CF2A3F10 | 48:63C8 | movsxd rcx,eax | eax = 04
00007FF6CF2A3F13 | 48:8D0449 | lea rax,qword ptr ds:[rcx+rcx*2] | rcx = 04
00007FF6CF2A3F17 | 48:8D0CC5 00000000 | lea rcx,qword ptr ds:[rax*8] | rax = 0C
00007FF6CF2A3F1F | 393C11 | cmp dword ptr ds:[rcx+rdx],edi |
00007FF6CF2A3F22 | 74 2F | je lineager.7FF6CF2A3F53 |
00007FF6CF2A3F24 | 8B4411 10 | mov eax,dword ptr ds:[rcx+rdx+0x10] |
00007FF6CF2A3F28 | 83F8 FF | cmp eax,0xFFFFFFFF |
00007FF6CF2A3F2B | 75 E3 | jne lineager.7FF6CF2A3F10 |
00007FF6CF2A3F2D | 48:8D5424 30 | lea rdx,qword ptr ss:[rsp+0x30] | 这里肯定不进,因为当前rdx不是栈地址
00007FF6CF2A3F32 | 48:8BCB | mov rcx,rbx |
00007FF6CF2A3F35 | E8 F627D0FE | call lineager.7FF6CDFA6730 |
00007FF6CF2A3F3A | 48:8B4C24 38 | mov rcx,qword ptr ss:[rsp+0x38] |
00007FF6CF2A3F3F | 48:85C9 | test rcx,rcx |
00007FF6CF2A3F42 | 74 27 | je lineager.7FF6CF2A3F6B |
00007FF6CF2A3F44 | 8939 | mov dword ptr ds:[rcx],edi |
00007FF6CF2A3F46 | 48:8971 08 | mov qword ptr ds:[rcx+0x8],rsi |
00007FF6CF2A3F4A | C741 10 FFFFFFFF | mov dword ptr ds:[rcx+0x10],0xFFFFFFFF |
00007FF6CF2A3F51 | EB 1B | jmp lineager.7FF6CF2A3F6E |
00007FF6CF2A3F53 | 48:8BC2 | mov rax,rdx | rdx = 00000288BD6DF940
00007FF6CF2A3F56 | 48:03C1 | add rax,rcx | rcx = 0x60 才是,0xD8 不是
00007FF6CF2A3F59 | 48:8D40 08 | lea rax,qword ptr ds:[rax+0x8] | rcx = 00000288BD6DFA18
00007FF6CF2A3F5D | 48:0F44C5 | cmove rax,rbp |
00007FF6CF2A3F61 | 48:85C0 | test rax,rax |
00007FF6CF2A3F64 | 74 C7 | je lineager.7FF6CF2A3F2D |
00007FF6CF2A3F66 | 48:8930 | mov qword ptr ds:[rax],rsi | 写入HP, rax = 00000288BD6DFA20
00007FF6CF2A3F69 | EB 23 | jmp lineager.7FF6CF2A3F8E |
00007FF6CF2A3F6B | 48:8BCD | mov rcx,rbp |
// PULONG HP指针 = [rcx + 0x158] + 0x60 + 0x8
00007FF6CDA1B940 + 00007FF6D0166BE0
// 分析上层函数传入的参数: rcx = 0x288BDAEE740
LineageR.exe+21359F0
00007FF6CF2F59F0 | 4C:894424 18 | mov qword ptr ss:[rsp+0x18],r8 |
00007FF6CF2F59F5 | 48:895424 10 | mov qword ptr ss:[rsp+0x10],rdx |
00007FF6CF2F59FA | 48:894C24 08 | mov qword ptr ss:[rsp+0x8],rcx |
00007FF6CF2F59FF | 53 | push rbx |
00007FF6CF2F5A00 | 55 | push rbp |
00007FF6CF2F5A01 | 56 | push rsi |
00007FF6CF2F5A02 | 57 | push rdi |
00007FF6CF2F5A03 | 41:54 | push r12 |
00007FF6CF2F5A05 | 41:55 | push r13 |
00007FF6CF2F5A07 | 41:56 | push r14 |
00007FF6CF2F5A09 | 41:57 | push r15 |
00007FF6CF2F5A0B | 48:83EC 38 | sub rsp,0x38 | 取这几句作为特征码进行搜索函数
00007FF6CF2F5A0F | 0F297424 20 | movaps xmmword ptr ss:[rsp+0x20],xmm6 |
00007FF6CF2F5A14 | 48:8BF2 | mov rsi,rdx |
00007FF6CF2F5A17 | E8 343C02FF | call lineager.7FF6CE319650 | 这里返回的是对象基址,可以直接调用,或者取基址也是可以的
00007FF6CF2F5A1C | 48:8BC8 | mov rcx,rax | 返回值: 0x7FF73E9DDB98 = LineageR.exe + 7EBDB98
00007FF6CF2F5A1F | E8 AC03ED00 | call lineager.7FF6D01C5DD0 | 这里返回的就是人物对象了
00007FF6CF2F5A24 | 4C:6346 30 | movsxd r8,dword ptr ds:[rsi+0x30] |
00007FF6CF2F5A28 | BA 0A000000 | mov edx,0xA | A:'\n'
00007FF6CF2F5A2D | 48:8BC8 | mov rcx,rax |
00007FF6CF2F5A30 | 4C:8BF0 | mov r14,rax |
00007FF6CF2F5A33 | E8 78E4FAFF | call lineager.7FF6CF2A3EB0 |
00007FF6CF2F5A38 | 48:635E 2C | movsxd rbx,dword ptr ds:[rsi+0x2C] |
00007FF6CF2F5A3C | BA 09000000 | mov edx,0x9 | 9:'\t'
00007FF6CF2F5A41 | 49:8BCE | mov rcx,r14 |
00007FF6CF2F5A44 | E8 B78CF8FF | call lineager.7FF6CF27E700 |
00007FF6CF2F5A49 | 48:3BD8 | cmp rbx,rax |
00007FF6CF2F5A4C | 74 1C | je lineager.7FF6CF2F5A6A |
00007FF6CF2F5A4E | 4C:8BC3 | mov r8,rbx |
00007FF6CF2F5A51 | BA 09000000 | mov edx,0x9 | 9:'\t'
00007FF6CF2F5A56 | 49:8BCE | mov rcx,r14 |
00007FF6CF2F5A59 | E8 52E4FAFF | call lineager.7FF6CF2A3EB0 |
00007FF6CF2F5A5E | 48:8D0D 13DF5F05 | lea rcx,qword ptr ds:[0x7FF6D48F3978] |
00007FF6CF2F5A65 | E8 86A572FE | call lineager.7FF6CDA1FFF0 |
00007FF6CF2F5A6A | 33D2 | xor edx,edx |
00007FF6CF2F5A6C | 49:8BCE | mov rcx,r14 |
00007FF6CF2F5A6F | E8 8C8CF8FF | call lineager.7FF6CF27E700 |
00007FF6CF2F5A74 | 4C:6366 18 | movsxd r12,dword ptr ds:[rsi+0x18] |
00007FF6CF2F5A78 | BE 01000000 | mov esi,0x1 |
00007FF6CF2F5A7D | 48:8BD8 | mov rbx,rax |
00007FF6CF2F5A80 | 44:8D6E 01 | lea r13d,qword ptr ds:[rsi+0x1] |
00007FF6CF2F5A84 | 85C0 | test eax,eax |
00007FF6CF2F5A86 | 7E 18 | jle lineager.7FF6CF2F5AA0 |
00007FF6CF2F5A88 | 41:3BDC | cmp ebx,r12d |
00007FF6CF2F5A8B | 7D 13 | jge lineager.7FF6CF2F5AA0 |
00007FF6CF2F5A8D | 4D:8BC4 | mov r8,r12 |
00007FF6CF2F5A90 | 33D2 | xor edx,edx |
00007FF6CF2F5A92 | 49:8BCE | mov rcx,r14 |
00007FF6CF2F5A95 | 44:0FB6FE | movzx r15d,sil |
00007FF6CF2F5A99 | E8 12E4FAFF | call lineager.7FF6CF2A3EB0 |
00007FF6CF2F5A9E | EB 19 | jmp lineager.7FF6CF2F5AB9 |
00007FF6CF2F5AA0 | 4D:8BC4 | mov r8,r12 |
00007FF6CF2F5AA3 | 33D2 | xor edx,edx |
00007FF6CF2F5AA5 | 49:8BCE | mov rcx,r14 |
00007FF6CF2F5AA8 | E8 03E4FAFF | call lineager.7FF6CF2A3EB0 | 调用上一个函数
00007FF6CF2F5AAD | 45:32FF | xor r15b,r15b |
00007FF6CF2F5AB0 | 41:3BDC | cmp ebx,r12d |
00007FF6CF2F5AB3 | 0F84 07010000 | je lineager.7FF6CF2F5BC0 |
00007FF6CF2F5AB9 | 8B0D E5DE5F05 | mov ecx,dword ptr ds:[0x7FF6D48F39A4] |
00007FF6CF2F5ABF | 40:32ED | xor bpl,bpl |
// 函数 LineageR.exe+3005DD0 : 该函数很多地方都在调用,传入不同的下标得到不同的对象
00007FF6D01C5DD0 | 44:8B41 04 | mov r8d,dword ptr ds:[rcx+0x4] | rcx来自一个常量
00007FF6D01C5DD4 | 45:85C0 | test r8d,r8d |
00007FF6D01C5DD7 | 74 4E | je lineager.7FF6D01C5E27 |
00007FF6D01C5DD9 | 8B01 | mov eax,dword ptr ds:[rcx] | 参数1进行计算
00007FF6D01C5DDB | 85C0 | test eax,eax |
00007FF6D01C5DDD | 78 48 | js lineager.7FF6D01C5E27 |
00007FF6D01C5DDF | 3B05 1FE5FF04 | cmp eax,dword ptr ds:[0x7FF6D51C4304] |
00007FF6D01C5DE5 | 7D 40 | jge lineager.7FF6D01C5E27 |
00007FF6D01C5DE7 | 99 | cdq |
00007FF6D01C5DE8 | 0FB7D2 | movzx edx,dx | dx = 0
00007FF6D01C5DEB | 03C2 | add eax,edx |
00007FF6D01C5DED | 8BC8 | mov ecx,eax |
00007FF6D01C5DEF | 0FB7C0 | movzx eax,ax |
00007FF6D01C5DF2 | 2BC2 | sub eax,edx | 这里rax还是等于rax
00007FF6D01C5DF4 | C1F9 10 | sar ecx,0x10 | rcx >>= 0x10, 实际就等于0了
00007FF6D01C5DF7 | 48:98 | cdqe |
00007FF6D01C5DF9 | 48:63C9 | movsxd rcx,ecx |
00007FF6D01C5DFC | 48:8D1440 | lea rdx,qword ptr ds:[rax+rax*2] | rdx = 3 * rax
00007FF6D01C5E00 | 48:8B05 E9E4FF04 | mov rax,qword ptr ds:[0x7FF6D51C42F0] | 这里就是人物对象基址了
00007FF6D01C5E07 | 48:8B0CC8 | mov rcx,qword ptr ds:[rax+rcx*8] | 应该是对象数组,rcx应该是下标,也有可能是周围怪物的整个数组
00007FF6D01C5E0B | 48:8D04D1 | lea rax,qword ptr ds:[rcx+rdx*8] | rax来自, rdx也有可能是下标
00007FF6D01C5E0F | 48:85C0 | test rax,rax |
00007FF6D01C5E12 | 74 13 | je lineager.7FF6D01C5E27 |
00007FF6D01C5E14 | 44:3940 10 | cmp dword ptr ds:[rax+0x10],r8d |
00007FF6D01C5E18 | 75 0D | jne lineager.7FF6D01C5E27 |
00007FF6D01C5E1A | F740 08 00000030 | test dword ptr ds:[rax+0x8],0x30000000 |
00007FF6D01C5E21 | 75 04 | jne lineager.7FF6D01C5E27 |
00007FF6D01C5E23 | 48:8B00 | mov rax,qword ptr ds:[rax] | 跟踪rax
00007FF6D01C5E26 | C3 | ret |
00007FF6D01C5E27 | 33C0 | xor eax,eax | 这里肯定是不进去的
00007FF6D01C5E29 | C3 | ret
// 人物对象下标 0x694A |
rcx = 常量 0x7FF73E9DDB98 = LineageR.exe + 7EBDB98 -> 0x694A
baseAddr = 0x7FF6D51C42F0 = LineageR.exe + 80042F0 -> 0x1D61417CC40
返回人物对象 = [[[baseAddr] + ([rcx] >> 0x10 * 8)] + ([rcx] + [rcx] * 2) * 8]
0 = ([rcx] >> 0x10] * 8) // 实际就是等于0
// 测试
9DEF0 = 0000694A * 3 * 8
rcx = [000001937F43CC40 + 0 * 8] = 000001937F830008
rdx = 000001937F830008 + 9DEF0 = 1937F8CDEF8
rax = [1937F8CDEF8] = 00000193B02F8F80
// CE表达式: 简化算法
[[0x7FF6D51C42F0] + [00007FF6D507CED8] * 3 * 8]
// 根据上面分析得到的改血值公式
// HP指针 = [00000193B02F8F80 + 0x158] + 0x60 + 0x8
// 伪代码: 看起来像是结构数组的一种取下标操作
RoleIndexOfAllObject = [LineageR.exe + 80042F0]
BaseeAllObjectList = [LineageR.exe + 7EBDB98]
*(PULONG64)(*(PULONG64)(BaseeAllObjectList + RoleIndexOfAllObject >> 0x10 * 8) + RoleIndexOfAllObject * 3 * 8)
// 再分析一下取人物下标指针的函数:
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+FD0 - 48 83 EC 28 - sub rsp,28 { 40 }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+FD4 - 65 48 8B 04 25 58000000 - mov rax,gs:[00000058] { 88 }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+FDD - 8B 0D AD380507 - mov ecx,[LineageR.exe+81ACF10] { (0) }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+FE3 - BA 54040000 - mov edx,00000454 { 1108 }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+FE8 - 48 8B 0C C8 - mov rcx,[rax+rcx*8]
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+FEC - 8B 04 0A - mov eax,[rdx+rcx]
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+FEF - 39 05 2B45D606 - cmp [LineageR.exe+7EBDBA0],eax { (-2147481119) }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+FF5 - 7F 0C - jg LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+1003
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+FF7 - 48 8D 05 1A45D606 - lea rax,[LineageR.exe+7EBDB98] { (26954) }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+FFE - 48 83 C4 28 - add rsp,28 { 40 }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+1002- C3 - ret
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+1003- 48 8D 0D 1645D606 - lea rcx,[LineageR.exe+7EBDBA0] { (-2147481119) }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+100A- E8 29901404 - call LineageR.exe+52A26B8
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+100F- 83 3D 0A45D606 FF - cmp dword ptr [LineageR.exe+7EBDBA0],-01 { (-2147481119),255 }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+1016- 75 DF - jne LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+FF7
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+1018- 48 8D 0D 0145D606 - lea rcx,[LineageR.exe+7EBDBA0] { (-2147481119) }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+101F- C7 05 EF44D606 FFFFFFFF - mov [LineageR.exe+7EBDB98],FFFFFFFF { (26954),-1 }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+1029- C7 05 E944D606 00000000 - mov [LineageR.exe+7EBDB9C],00000000 { (3002),0 }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+1033- E8 A08F1404 - call LineageR.exe+52A2658
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+1038- 48 8D 05 D944D606 - lea rax,[LineageR.exe+7EBDB98] { (26954) } // 这里就是返回的对象基址,有可能是所有对象基址
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+103F- 48 83 C4 28 - add rsp,28 { 40 }
LineageR.AK::SoundEngine::UnregisterResourceMonitorCallback+1043- C3 - ret
// MP指针 = HP指针 + 0x18
------------------- 刚分析完一个晚上游戏就更新了,NMMP ---------------
// LineageR.exe + 212E180
00007FF74D6EE180 | 4C:894424 18 | mov qword ptr ss:[rsp+0x18],r8 |
00007FF74D6EE185 | 48:895424 10 | mov qword ptr ss:[rsp+0x10],rdx |
00007FF74D6EE18A | 48:894C24 08 | mov qword ptr ss:[rsp+0x8],rcx |
00007FF74D6EE18F | 53 | push rbx |
00007FF74D6EE190 | 55 | push rbp |
00007FF74D6EE191 | 56 | push rsi |
00007FF74D6EE192 | 57 | push rdi |
00007FF74D6EE193 | 41:54 | push r12 |
00007FF74D6EE195 | 41:55 | push r13 |
00007FF74D6EE197 | 41:56 | push r14 |
00007FF74D6EE199 | 41:57 | push r15 |
00007FF74D6EE19B | 48:83EC 38 | sub rsp,0x38 |
00007FF74D6EE19F | 0F297424 20 | movaps xmmword ptr ss:[rsp+0x20],xmm6 |
00007FF74D6EE1A4 | 48:8BF2 | mov rsi,rdx |
00007FF74D6EE1A7 | E8 C4B702FF | call lineager.7FF74C719970 | 返回人物对象下标指针
00007FF74D6EE1AC | 48:8BC8 | mov rcx,rax |
00007FF74D6EE1AF | E8 DC17EE00 | call lineager.7FF74E5CF990 | 返回人物对象
00007FF74D6EE1B4 | 4C:6346 30 | movsxd r8,dword ptr ds:[rsi+0x30] |
00007FF74D6EE1B8 | BA 0A000000 | mov edx,0xA | A:'\n'
00007FF74D6EE1BD | 48:8BC8 | mov rcx,rax |
00007FF74D6EE1C0 | 4C:8BF0 | mov r14,rax |
00007FF74D6EE1C3 | E8 783FFAFF | call lineager.7FF74D692140 |
00007FF74D6EE1C8 | 48:635E 2C | movsxd rbx,dword ptr ds:[rsi+0x2C] |
00007FF74D6EE1CC | BA 09000000 | mov edx,0x9 | 9:'\t'
00007FF74D6EE1D1 | 49:8BCE | mov rcx,r14 |
00007FF74D6EE1D4 | E8 E7FDF7FF | call lineager.7FF74D66DFC0 |
00007FF74D6EE1D9 | 48:3BD8 | cmp rbx,rax |
00007FF74D6EE1DC | 74 1C | je lineager.7FF74D6EE1FA |
00007FF74D6EE1DE | 4C:8BC3 | mov r8,rbx |
00007FF74D6EE1E1 | BA 09000000 | mov edx,0x9 | 9:'\t'
00007FF74D6EE1E6 | 49:8BCE | mov rcx,r14 |
00007FF74D6EE1E9 | E8 523FFAFF | call lineager.7FF74D692140 |
00007FF74D6EE1EE | 48:8D0D AB486105 | lea rcx,qword ptr ds:[0x7FF752D02AA0] |
00007FF74D6EE1F5 | E8 561E73FE | call lineager.7FF74BE20050 |
00007FF74D6EE1FA | 33D2 | xor edx,edx |
00007FF74D6EE1FC | 49:8BCE | mov rcx,r14 |
00007FF74D6EE1FF | E8 BCFDF7FF | call lineager.7FF74D66DFC0 |
00007FF74D6EE204 | 4C:6366 18 | movsxd r12,dword ptr ds:[rsi+0x18] |
00007FF74D6EE208 | BE 01000000 | mov esi,0x1 |
00007FF74D6EE20D | 48:8BD8 | mov rbx,rax |
00007FF74D6EE210 | 44:8D6E 01 | lea r13d,qword ptr ds:[rsi+0x1] |
00007FF74D6EE214 | 85C0 | test eax,eax |
00007FF74D6EE216 | 7E 18 | jle lineager.7FF74D6EE230 |
// 上面的 LineageR.exe+3005DD0 更新为
// LineageR.exe + 300F990, 参数就是人物对象下标
00007FF74E5CF990 | 44:8B41 04 | mov r8d,dword ptr ds:[rcx+0x4] |
00007FF74E5CF994 | 45:85C0 | test r8d,r8d |
00007FF74E5CF997 | 74 4E | je lineager.7FF74E5CF9E7 |
00007FF74E5CF999 | 8B01 | mov eax,dword ptr ds:[rcx] | rcx:L"汨傺翷"
00007FF74E5CF99B | 85C0 | test eax,eax |
00007FF74E5CF99D | 78 48 | js lineager.7FF74E5CF9E7 |
00007FF74E5CF99F | 3B05 9F610005 | cmp eax,dword ptr ds:[0x7FF7535D5B44] |
00007FF74E5CF9A5 | 7D 40 | jge lineager.7FF74E5CF9E7 |
00007FF74E5CF9A7 | 99 | cdq |
00007FF74E5CF9A8 | 0FB7D2 | movzx edx,dx |
00007FF74E5CF9AB | 03C2 | add eax,edx |
00007FF74E5CF9AD | 8BC8 | mov ecx,eax |
00007FF74E5CF9AF | 0FB7C0 | movzx eax,ax |
00007FF74E5CF9B2 | 2BC2 | sub eax,edx |
00007FF74E5CF9B4 | C1F9 10 | sar ecx,0x10 |
00007FF74E5CF9B7 | 48:98 | cdqe |
00007FF74E5CF9B9 | 48:63C9 | movsxd rcx,ecx |
00007FF74E5CF9BC | 48:8D1440 | lea rdx,qword ptr ds:[rax+rax*2] |
00007FF74E5CF9C0 | 48:8B05 69610005 | mov rax,qword ptr ds:[0x7FF7535D5B30] | 这里就是人物对象基址了
00007FF74E5CF9C7 | 48:8B0CC8 | mov rcx,qword ptr ds:[rax+rcx*8] |
00007FF74E5CF9CB | 48:8D04D1 | lea rax,qword ptr ds:[rcx+rdx*8] |
00007FF74E5CF9CF | 48:85C0 | test rax,rax |
00007FF74E5CF9D2 | 74 13 | je lineager.7FF74E5CF9E7 |
00007FF74E5CF9D4 | 44:3940 10 | cmp dword ptr ds:[rax+0x10],r8d |
00007FF74E5CF9D8 | 75 0D | jne lineager.7FF74E5CF9E7 |
00007FF74E5CF9DA | F740 08 00000030 | test dword ptr ds:[rax+0x8],0x30000000 |
00007FF74E5CF9E1 | 75 04 | jne lineager.7FF74E5CF9E7 |
00007FF74E5CF9E3 | 48:8B00 | mov rax,qword ptr ds:[rax] |
00007FF74E5CF9E6 | C3 | ret |
00007FF74E5CF9E7 | 33C0 | xor eax,eax |
00007FF74E5CF9E9 | C3 | ret |
// 取人物下标指针的函数
// LineageR.exe + 1159970
00007FF74C719970 | 48:83EC 28 | sub rsp,0x28 |
00007FF74C719974 | 6548:8B0425 58000000 | mov rax,qword ptr gs:[0x58] |
00007FF74C71997D | 8B0D CD4D0607 | mov ecx,dword ptr ds:[0x7FF75377E750] |
00007FF74C719983 | BA 54040000 | mov edx,0x454 |
00007FF74C719988 | 48:8B0CC8 | mov rcx,qword ptr ds:[rax+rcx*8] |
00007FF74C71998C | 8B040A | mov eax,dword ptr ds:[rdx+rcx] |
00007FF74C71998F | 3905 8B57D706 | cmp dword ptr ds:[0x7FF75348F120],eax | 这里返回 0x6A93, LineageR.exe + 7ECF120
00007FF74C719995 | 7F 0C | jg lineager.7FF74C7199A3 |
00007FF74C719997 | 48:8D05 7A57D706 | lea rax,qword ptr ds:[0x7FF75348F118] | 这里返回 0x69CC, LineageR.exe + 7ECF118, 这句才是返回的人物下标, 取物征码要取这里
00007FF74C71999E | 48:83C4 28 | add rsp,0x28 |
00007FF74C7199A2 | C3 | ret |
00007FF74C7199A3 | 48:8D0D 7657D706 | lea rcx,qword ptr ds:[0x7FF75348F120] | 这是另一个函数了
00007FF74C7199AA | E8 D9291504 | call lineager.7FF75086C388 |
00007FF74C7199AF | 833D 6A57D706 FF | cmp dword ptr ds:[0x7FF75348F120],0xFFFFFFFF |
00007FF74C7199B6 | 75 DF | jne lineager.7FF74C719997 |
00007FF74C7199B8 | 48:8D0D 6157D706 | lea rcx,qword ptr ds:[0x7FF75348F120] |
00007FF74C7199BF | C705 4F57D706 FFFFFFFF | mov dword ptr ds:[0x7FF75348F118],0xFFFFFFFF |
00007FF74C7199C9 | C705 4957D706 00000000 | mov dword ptr ds:[0x7FF75348F11C],0x0 |
00007FF74C7199D3 | E8 50291504 | call lineager.7FF75086C328 |
00007FF74C7199D8 | 48:8D05 3957D706 | lea rax,qword ptr ds:[0x7FF75348F118] |
00007FF74C7199DF | 48:83C4 28 | add rsp,0x28 |
00007FF74C7199E3 | C3 | ret |
// 人物对象下标 0x69CC 或者 0x6A93,这里具体是哪个值还需要跟一下 00007FF74D6EE1A7 这句代码
// 根据测试,0x69CC就是不物下标, 注意人物的常量下标值是动态的, 所以必须取基址
rcx = 常量 0x7FF73E9DDB98 = LineageR.exe + 7ECF118 -> 0x6A02
baseAddr = 0x7FF7535D5B30 = LineageR.exe + 8015B30 -> 0x1CEABDDCB20 // 注意这里的偏移是给的是X64dbg的偏移
返回人物对象 = [[[baseAddr] + ([rcx] >> 0x10 * 8)] + ([rcx] + [rcx] * 2) * 8]
// 伪代码: 看起来像是结构数组的一种取下标操作
RoleIndexOfAllObject = [LineageR.exe + 7ECF118]
BaseeAllObjectList = [LineageR.exe + 8015B30]
*(PULONG64)(*(PULONG64)(BaseeAllObjectList + RoleIndexOfAllObject >> 0x10 * 8) + RoleIndexOfAllObject * 3 * 8)
// HP公式
PULONG HP指针 = [rcx + 0x158] + 0x60 + 0x8
// 测试
9F030 = 0x6A02 * 3 * 8
rcx = [000002010157CC40 + 0 * 8] = 20101960008
rdx = 20101960008 + 9F030 = 201019FF038
rax = [201019FF038] = 201306F0F40
// CE表达式: 简化算法
[[000002010157CC40] + 9F030]
// 根据上面分析得到的改血值公式
// HP指针 = [201306F0F40 + 0x158] + 0x60 + 0x8