SunBeam wrote: ↑Mon Aug 28, 2017 9:26 pm
Alright folks, I got a ton shit of stuff I debugged with the CPY version (v2355883). Sure, you can easily port it to the newest Ubisoft one
Here goes...
#1. This function reads your
Level when J-menu is open:
Code: Select all
GRW.exe+4C0F930 - 48 89 5C 24 08 - mov [rsp+08],rbx // GetLevel
GRW.exe+4C0F935 - 57 - push rdi
GRW.exe+4C0F936 - 48 83 EC 20 - sub rsp,20
GRW.exe+4C0F93A - 48 8D 59 10 - lea rbx,[rcx+10]
GRW.exe+4C0F93E - 48 89 CF - mov rdi,rcx
GRW.exe+4C0F941 - 48 85 DB - test rbx,rbx
GRW.exe+4C0F944 - 74 08 - je GRW.exe+4C0F94E
GRW.exe+4C0F946 - 48 89 D9 - mov rcx,rbx
GRW.exe+4C0F949 - E8 72F0CF02 - call GRW.exe+790E9C0
GRW.exe+4C0F94E - 48 8D 4F 40 - lea rcx,[rdi+40]
GRW.exe+4C0F952 - E8 C938E4FF - call GRW.exe+4A53220 // Decrypt
GRW.exe+4C0F957 - 89 C7 - mov edi,eax // EAX here will show your current level
GRW.exe+4C0F959 - 48 85 DB - test rbx,rbx
GRW.exe+4C0F95C - 74 0A - je GRW.exe+4C0F968
GRW.exe+4C0F95E - 48 89 D9 - mov rcx,rbx
GRW.exe+4C0F961 - E8 2A1D0F03 - call GRW.exe+7D01690
GRW.exe+4C0F966 - 89 F8 - mov eax,edi
GRW.exe+4C0F968 - 48 8B 5C 24 30 - mov rbx,[rsp+30]
GRW.exe+4C0F96D - 48 83 C4 20 - add rsp,20
GRW.exe+4C0F971 - 5F - pop rdi
GRW.exe+4C0F972 - C3 - ret
#2. This location will READ and DECRYPT the 4
Resources:
Code: Select all
GRW.exe+6648D41 - 0FB7 AE 56130000 - movzx ebp,word ptr [rsi+1356] // value is 0x4 (4 resources)
GRW.exe+6648D48 - 48 8B 9E 4C130000 - mov rbx,[rsi+0000134C] // 00007FF5FD245BE0 == pointer to first resource to process
GRW.exe+6648D4F - C1 E5 03 - shl ebp,3 // this makes ebp 0x20
GRW.exe+6648D52 - 48 01 DD - add rbp,rbx // this adds the base; rbp becomes end of 4*0x8 resourcing pointers
GRW.exe+6648D55 - 48 39 EB - cmp rbx,rbp
GRW.exe+6648D58 - 0F84 D4000000 - je GRW.exe+6648E32
GRW.exe+6648D5E - 4C 89 74 24 50 - mov [rsp+50],r14
GRW.exe+6648D63 - 48 8B 03 - mov rax,[rbx]
GRW.exe+6648D66 - 48 63 48 0C - movsxd rcx,dword ptr [rax+0C]
GRW.exe+6648D6A - 48 8B 00 - mov rax,[rax] // read first pointer
GRW.exe+6648D6D - 48 C1 E1 20 - shl rcx,20
GRW.exe+6648D71 - 48 C1 F9 3F - sar rcx,3F
GRW.exe+6648D75 - 48 21 C8 - and rax,rcx
GRW.exe+6648D78 - 8B 48 28 - mov ecx,[rax+28] // get resource id for loop processing
GRW.exe+6648D7B - E8 C04FAAFE - call GRW.exe+50EDD40 // returns 1, 2, 3, 4 :) function takes in the resource id and works up the iterator
GRW.exe+6648D80 - 0FB7 8E AE120000 - movzx ecx,word ptr [rsi+12AE] // gets value 0x5
GRW.exe+6648D87 - 39 C8 - cmp eax,ecx // check's done here
GRW.exe+6648D89 - 0F83 9E000000 - jae GRW.exe+6648E2D // if >= 5, jumps
GRW.exe+6648D8F - 8D 0C C5 00000000 - lea ecx,[rax*8]
GRW.exe+6648D96 - 48 8B 86 A4120000 - mov rax,[rsi+12A4]
GRW.exe+6648D9D - 48 8B 3C 01 - mov rdi,[rcx+rax]
GRW.exe+6648DA1 - 48 85 FF - test rdi,rdi
GRW.exe+6648DA4 - 0F84 83000000 - je GRW.exe+6648E2D
GRW.exe+6648DAA - 48 8B 0D 8F67C9FD - mov rcx,[GRW.exe+42DF540] // get pBase pointer -> 00007FF5F94AD098
GRW.exe+6648DB1 - 48 89 DA - mov rdx,rbx // pointers are in this order: 00007FF5FD245BE0 (16775), 00007FF5FD245BE8 (13300), 00007FF5FD245BF0 (5500), 00007FF5FD245BF8 (5625)
// where: 16775 = Gasoline; 13300 = Medical Supplies; 5500 = Comms Tools; 5625 = Food Supplies
// and the ids for the loop: Gasoline - 1; Medical Supplies - 3; Comms Tools - 2; Food Supplies - 0
GRW.exe+6648DB4 - E8 B74459FE - call GRW.exe+4BDD270
GRW.exe+6648E20 - 48 83 C3 08 - add rbx,8 // do the loop to read all resources
GRW.exe+6648E24 - 48 39 EB - cmp rbx,rbp // check if done
GRW.exe+6648E27 - 0F85 36FFFFFF - jne GRW.exe+6648D63 // yes, loop; no, exit
The above was my run-down on the current resources I have at this stage.
#3. This location will ENCRYPT and WRITE the
Resource as you tag the various crates or trucks etc.:
Code: Select all
GRW.exe+4BDC430 - 66 41 0F6E 44 04 0C - movd xmm0,[r12+rax+0C]
GRW.exe+4BDC437 - 0F5B C0 - cvtdq2ps xmm0,xmm0
GRW.exe+4BDC43A - F3 0F59 C6 - mulss xmm0,xmm6
GRW.exe+4BDC43E - F3 0F2C F0 - cvttss2si esi,xmm0
GRW.exe+4BDC442 - 85 F6 - test esi,esi
GRW.exe+4BDC444 - 0F48 F3 - cmovs esi,ebx
GRW.exe+4BDC447 - 41 89 F0 - mov r8d,esi // r8d == 2500 (amount to encode and write); rdx == our resource identifer; rcx == pointer to pointer to table of pointers to resources
GRW.exe+4BDC44A - E8 21030000 - call GRW.exe+4BDC770
GRW.exe+4BDC44F - 84 C0 - test al,al
GRW.exe+4BDC451 - 0F84 F9010000 - je GRW.exe+4BDC650
..
..
..
GRW.exe+4BDC7D4 - 01 F0 - add eax,esi // add amount here
GRW.exe+4BDC7D6 - 49 89 D8 - mov r8,rbx // r8 == resource identifier
GRW.exe+4BDC7D9 - 41 89 C1 - mov r9d,eax // r9 == added amount
GRW.exe+4BDC7DC - E8 0F653000 - call GRW.exe+4EE2CF0 // encode and write value
#4. And the encrypt/decrypt functions:
Code: Select all
// read and decrypt
GRW.exe+4A53220 - 48 89 5C 24 08 - mov [rsp+08],rbx
GRW.exe+4A53225 - 48 8B 01 - mov rax,[rcx]
GRW.exe+4A53228 - 31 D2 - xor edx,edx
GRW.exe+4A5322A - 49 89 C8 - mov r8,rcx
GRW.exe+4A5322D - 44 0FB6 08 - movzx r9d,byte ptr [rax]
GRW.exe+4A53231 - 48 8B 41 08 - mov rax,[rcx+08]
GRW.exe+4A53235 - 44 0FB6 10 - movzx r10d,byte ptr [rax]
GRW.exe+4A53239 - 48 8B 41 10 - mov rax,[rcx+10]
GRW.exe+4A5323D - 44 0FB6 18 - movzx r11d,byte ptr [rax]
GRW.exe+4A53241 - 48 8B 41 18 - mov rax,[rcx+18]
GRW.exe+4A53245 - 89 D1 - mov ecx,edx
GRW.exe+4A53247 - 0FB6 18 - movzx ebx,byte ptr [rax]
GRW.exe+4A5324A - 41 0FB6 C1 - movzx eax,r9l
GRW.exe+4A5324E - 41 D0 E9 - shr r9l,1
GRW.exe+4A53251 - 83 E0 01 - and eax,01
GRW.exe+4A53254 - D3 E0 - shl eax,cl
GRW.exe+4A53256 - FF C1 - inc ecx
GRW.exe+4A53258 - 09 C2 - or edx,eax
GRW.exe+4A5325A - 41 0FB6 C2 - movzx eax,r10l
GRW.exe+4A5325E - 41 D0 EA - shr r10l,1
GRW.exe+4A53261 - 83 E0 01 - and eax,01
GRW.exe+4A53264 - D3 E0 - shl eax,cl
GRW.exe+4A53266 - FF C1 - inc ecx
GRW.exe+4A53268 - 09 C2 - or edx,eax
GRW.exe+4A5326A - 41 0FB6 C3 - movzx eax,r11l
GRW.exe+4A5326E - 41 D0 EB - shr r11l,1
GRW.exe+4A53271 - 83 E0 01 - and eax,01
GRW.exe+4A53274 - D3 E0 - shl eax,cl
GRW.exe+4A53276 - FF C1 - inc ecx
GRW.exe+4A53278 - 09 C2 - or edx,eax
GRW.exe+4A5327A - 0FB6 C3 - movzx eax,bl
GRW.exe+4A5327D - D0 EB - shr bl,1
GRW.exe+4A5327F - 83 E0 01 - and eax,01
GRW.exe+4A53282 - D3 E0 - shl eax,cl
GRW.exe+4A53284 - FF C1 - inc ecx
GRW.exe+4A53286 - 09 C2 - or edx,eax
GRW.exe+4A53288 - 83 F9 20 - cmp ecx,20
GRW.exe+4A5328B - 7C BD - jl GRW.exe+4A5324A
GRW.exe+4A5328D - 41 8B 40 20 - mov eax,[r8+20]
GRW.exe+4A53291 - 48 8B 5C 24 08 - mov rbx,[rsp+08]
GRW.exe+4A53296 - 31 D0 - xor eax,edx
GRW.exe+4A53298 - C3 - ret
Code: Select all
// encrypt and write
GRW.exe+4A897E0 - 8B 41 20 - mov eax,[rcx+20]
GRW.exe+4A897E3 - 49 89 C8 - mov r8,rcx
GRW.exe+4A897E6 - 48 8B 49 18 - mov rcx,[rcx+18]
GRW.exe+4A897EA - C6 01 00 - mov byte ptr [rcx],00
GRW.exe+4A897ED - 49 8B 48 10 - mov rcx,[r8+10]
GRW.exe+4A897F1 - 31 D0 - xor eax,edx
GRW.exe+4A897F3 - C6 01 00 - mov byte ptr [rcx],00
GRW.exe+4A897F6 - 49 8B 48 08 - mov rcx,[r8+08]
GRW.exe+4A897FA - C6 01 00 - mov byte ptr [rcx],00
GRW.exe+4A897FD - 49 8B 08 - mov rcx,[r8]
GRW.exe+4A89800 - C6 01 00 - mov byte ptr [rcx],00
GRW.exe+4A89803 - 31 C9 - xor ecx,ecx
GRW.exe+4A89805 - 4D 8B 08 - mov r9,[r8]
GRW.exe+4A89808 - 0FB6 D0 - movzx edx,al
GRW.exe+4A8980B - D1 E8 - shr eax,1
GRW.exe+4A8980D - 80 E2 01 - and dl,01
GRW.exe+4A89810 - D2 E2 - shl dl,cl
GRW.exe+4A89812 - 41 08 11 - or [r9],dl
GRW.exe+4A89815 - 4D 8B 48 08 - mov r9,[r8+08]
GRW.exe+4A89819 - 0FB6 D0 - movzx edx,al
GRW.exe+4A8981C - 80 E2 01 - and dl,01
GRW.exe+4A8981F - D1 E8 - shr eax,1
GRW.exe+4A89821 - D2 E2 - shl dl,cl
GRW.exe+4A89823 - 41 08 11 - or [r9],dl
GRW.exe+4A89826 - 4D 8B 48 10 - mov r9,[r8+10]
GRW.exe+4A8982A - 0FB6 D0 - movzx edx,al
GRW.exe+4A8982D - 80 E2 01 - and dl,01
GRW.exe+4A89830 - D1 E8 - shr eax,1
GRW.exe+4A89832 - D2 E2 - shl dl,cl
GRW.exe+4A89834 - 41 08 11 - or [r9],dl
GRW.exe+4A89837 - 4D 8B 48 18 - mov r9,[r8+18]
GRW.exe+4A8983B - 0FB6 D0 - movzx edx,al
GRW.exe+4A8983E - 80 E2 01 - and dl,01
GRW.exe+4A89841 - D1 E8 - shr eax,1
GRW.exe+4A89843 - D2 E2 - shl dl,cl
GRW.exe+4A89845 - FF C1 - inc ecx
GRW.exe+4A89847 - 41 08 11 - or [r9],dl
GRW.exe+4A8984A - 83 F9 08 - cmp ecx,08
GRW.exe+4A8984D - 7C B6 - jl GRW.exe+4A89805
GRW.exe+4A8984F - F3 C3 - repe ret
#5. Additional locations where
Level and
XP are retrieved/processed:
Code: Select all
GRW.exe+4C11120 - 48 89 5C 24 08 - mov [rsp+08],rbx
GRW.exe+4C11125 - 48 89 74 24 10 - mov [rsp+10],rsi
GRW.exe+4C1112A - 57 - push rdi
GRW.exe+4C1112B - 48 83 EC 20 - sub rsp,20
GRW.exe+4C1112F - 48 8D 59 10 - lea rbx,[rcx+10]
GRW.exe+4C11133 - 48 89 D6 - mov rsi,rdx
GRW.exe+4C11136 - 48 89 CF - mov rdi,rcx
GRW.exe+4C11139 - 48 85 DB - test rbx,rbx
GRW.exe+4C1113C - 74 08 - je GRW.exe+4C11146
GRW.exe+4C1113E - 48 89 D9 - mov rcx,rbx
GRW.exe+4C11141 - E8 7AD8CF02 - call GRW.exe+790E9C0
GRW.exe+4C11146 - 48 8D 4F 40 - lea rcx,[rdi+40]
GRW.exe+4C1114A - E8 D120E4FF - call GRW.exe+4A53220 // call gets and decrypts your Level
GRW.exe+4C1114F - 48 8D 4F 68 - lea rcx,[rdi+68]
GRW.exe+4C11153 - 89 46 44 - mov [rsi+44],eax
GRW.exe+4C11156 - E8 C520E4FF - call GRW.exe+4A53220 // this call gets and decrypts your current XP
GRW.exe+4C1115B - 48 8D 8F A0000000 - lea rcx,[rdi+000000A0]
GRW.exe+4C11162 - 89 46 40 - mov [rsi+40],eax
GRW.exe+4C11165 - 0FB6 87 40010000 - movzx eax,byte ptr [rdi+00000140]
GRW.exe+4C1116C - 88 46 50 - mov [rsi+50],al
GRW.exe+4C1116F - E8 AC20E4FF - call GRW.exe+4A53220
GRW.exe+4C11174 - 48 8D 8F C8000000 - lea rcx,[rdi+000000C8]
GRW.exe+4C1117B - 89 46 4C - mov [rsi+4C],eax
GRW.exe+4C1117E - E8 9D20E4FF - call GRW.exe+4A53220
GRW.exe+4C11183 - 89 46 48 - mov [rsi+48],eax
GRW.exe+4C11186 - 48 85 DB - test rbx,rbx
GRW.exe+4C11189 - 74 08 - je GRW.exe+4C11193
GRW.exe+4C1118B - 48 89 D9 - mov rcx,rbx
GRW.exe+4C1118E - E8 FD040F03 - call GRW.exe+7D01690
GRW.exe+4C11193 - 48 8B 5C 24 30 - mov rbx,[rsp+30]
GRW.exe+4C11198 - 48 8B 74 24 38 - mov rsi,[rsp+38]
GRW.exe+4C1119D - 48 83 C4 20 - add rsp,20
GRW.exe+4C111A1 - 5F - pop rdi
GRW.exe+4C111A2 - C3 - ret
The next pieces of code are checked on various situations (haven't been able to pin-point all of them), but there's one in particular -- fly out the drone and try tagging AIs
Code: Select all
GRW.exe+4C0DDA3 - 4D 8D 67 40 - lea r12,[r15+40]
GRW.exe+4C0DDA7 - 4C 89 E1 - mov rcx,r12
GRW.exe+4C0DDAA - 4C 89 65 07 - mov [rbp+07],r12
GRW.exe+4C0DDAE - E8 6D54E4FF - call GRW.exe+4A53220// get and decrypt Level
GRW.exe+4C0DDB3 - 48 8B 0D 56CB6DFF - mov rcx,[GRW.exe+42EA910]
GRW.exe+4C0DDBA - 89 C7 - mov edi,eax
GRW.exe+4C0DDBC - E8 4F384700 - call GRW.exe+5081610 // get value 30
GRW.exe+4C0DDC1 - 39 C7 - cmp edi,eax // check your Level against 30
GRW.exe+4C0DDC3 - 0F8D EB030000 - jnl GRW.exe+4C0E1B4 // check on Drone tagging
Code: Select all
GRW.exe+4C0DF4C - E8 CF52E4FF - call GRW.exe+4A53220
GRW.exe+4C0DF51 - 4C 8B 35 B8C96DFF - mov r14,[GRW.exe+42EA910]
GRW.exe+4C0DF58 - 41 0FB7 4E 2A - movzx ecx,word ptr [r14+2A]
GRW.exe+4C0DF5D - 8D 78 FF - lea edi,[rax-01]
GRW.exe+4C0DF60 - 89 7D C3 - mov [rbp-3D],edi
GRW.exe+4C0DF63 - 39 CF - cmp edi,ecx // compare Level-1 against 30-1
GRW.exe+4C0DF65 - 0F83 3B010000 - jae GRW.exe+4C0E0A6 // check on Drone tagging
And lastly, this nifty piece of code where both
XP and
Level are processed when you kill an AI (yeah, you get 15 XP for killing regular narcos, I've not checked the amount on other types):
Code: Select all
GRW.exe+4C0DF2E - E8 ED52E4FF - call GRW.exe+4A53220 // read and decrypt XP
GRW.exe+4C0DF33 - 48 89 F9 - mov rcx,rdi
GRW.exe+4C0DF36 - 8D 14 06 - lea edx,[rsi+rax] // add
GRW.exe+4C0DF39 - E8 A2B8E7FF - call GRW.exe+4A897E0 // encrypt and write XP
GRW.exe+4C0DF3E - 4C 89 E1 - mov rcx,r12
GRW.exe+4C0DF41 - E8 DA52E4FF - call GRW.exe+4A53220 // read and decrypt Level
GRW.exe+4C0DF46 - 4C 89 E1 - mov rcx,r12
GRW.exe+4C0DF49 - 89 45 DF - mov [rbp-21],eax
GRW.exe+4C0DF4C - E8 CF52E4FF - call GRW.exe+4A53220 // do it again
GRW.exe+4C0DF51 - 4C 8B 35 B8C96DFF - mov r14,[GRW.exe+42EA910]
GRW.exe+4C0DF58 - 41 0FB7 4E 2A - movzx ecx,word ptr [r14+2A]
GRW.exe+4C0DF5D - 8D 78 FF - lea edi,[rax-01]
GRW.exe+4C0DF60 - 89 7D C3 - mov [rbp-3D],edi
GRW.exe+4C0DF63 - 39 CF - cmp edi,ecx // check Level-1 against 30-1
GRW.exe+4C0DF65 - 0F83 3B010000 - jae GRW.exe+4C0E0A6
GRW.exe+4C0DF6B - 8D 1C FD 00000000 - lea ebx,[rdi*8+00000000]
GRW.exe+4C0DF72 - 48 8B 4D FF - mov rcx,[rbp-01]
GRW.exe+4C0DF76 - E8 A552E4FF - call GRW.exe+4A53220 // read and decrypt XP again
GRW.exe+4C0DF7B - 49 8B 4E 20 - mov rcx,[r14+20]
GRW.exe+4C0DF7F - 48 8B 14 19 - mov rdx,[rcx+rbx] // get pointer to Max XP till leveling up
GRW.exe+4C0DF83 - 3B 42 10 - cmp eax,[rdx+10] // read value here
GRW.exe+4C0DF86 - 0F8C 0F010000 - jl GRW.exe+4C0E09B // check if below
GRW.exe+4C0DF8C - 4C 89 E1 - mov rcx,r12 // else increase Level
GRW.exe+4C0DF8F - E8 8C52E4FF - call GRW.exe+4A53220 // read and decrypt Level
GRW.exe+4C0DF94 - 4C 89 E1 - mov rcx,r12
GRW.exe+4C0DF97 - 8D 50 01 - lea edx,[rax+01] // encrypt and write Level
GRW.exe+4C0DF9A - E8 41B8E7FF - call GRW.exe+4A897E0
GRW.exe+4C0DF9F - 4C 8B 35 6AC96DFF - mov r14,[GRW.exe+42EA910]
GRW.exe+4C0DFA6 - 44 89 EE - mov esi,r13d
GRW.exe+4C0DFA9 - 49 8B 7E 20 - mov rdi,[r14+20]
GRW.exe+4C0DFAD - 48 8B 3C 3B - mov rdi,[rbx+rdi]
GRW.exe+4C0DFB1 - 66 44 3B 6F 1E - cmp r13w,[rdi+1E]
GRW.exe+4C0DFB6 - 0F83 C7000000 - jae GRW.exe+4C0E083
GRW.exe+4C0DFBC - 45 89 EE - mov r14d,r13d
GRW.exe+4C0DFBF - 4C 8B 05 4A128BFF - mov r8,[GRW.exe+44BF210]
GRW.exe+4C0DFC6 - BA 01000000 - mov edx,00000001 { 1 }
GRW.exe+4C0DFCB - 4C 89 6D E7 - mov [rbp-19],r13
GRW.exe+4C0DFCF - 8D 4A 07 - lea ecx,[rdx+07]
GRW.exe+4C0DFD2 - E8 095C1901 - call GRW.exe+5DA3BE0
GRW.exe+4C0DFD7 - BA 01000000 - mov edx,00000001
GRW.exe+4C0DFDC - 8D 4A 07 - lea ecx,[rdx+07]
GRW.exe+4C0DFDF - 49 89 C0 - mov r8,rax
GRW.exe+4C0DFE2 - E8 49F99900 - call GRW.exe+55AD930
GRW.exe+4C0DFE7 - 49 83 C9 FF - or r9,-01
GRW.exe+4C0DFEB - 4C 8D 05 C60F5EFE - lea r8,[GRW.exe+31EEFB8] // "LevelUp"
Suffices to say NOP-ing the JL at GRW.exe+4C0DF86 will give you instant
Level 30 for killing a few narcos. I then noticed the game increases their strength, as they die harder (from 3-4 hits, as opposed to 1-2 when at your level). Of course, I've not upgraded everything to match their strength, that's probably why
Will update table, check first post later.
BR,
Sun
EDIT: Table updated; re-download from first post.