Hey all, I am new here and been messing with making tables and learning. I recenetly posted a table I made for final fantasy 13 that somebody had requested a table for. It was ironically the game I chose to practice on.
Anyway, I am working on a give all items code and I have it able to give all basic items (potions, elixirs, antidotes, etc...)
Now I swear there is a better way to write the code in, its a simple inventory system, just input item id name and just a couple bytes later input quantity.
(green is the item id, which I currently have displayed per byte) (red is the quantity)
[Link]
My question is how would you personally go about writing that code into the game?
The way I did it, I feel has to be the long route and I feel there must be a better way to go about inputting all that info and don't want to continue writing code for it if its not an efficient way.
I have it writing the hex amount skip 4 bytes write again, until it finishes the name and then input quantity.
I was thinking like a table that could be called and just fills the bytes in automatically instead of having to control it jumping around.
There is nothing around the area besides the inventory, much further down is weapons, then accessories, materials, then final key items.
I don't want to make it jump around so much for so many items. I just can't see it being efficient lol.
Give all items
Re: Give all items
First-up, you have to understand what is it you want to do. Then think "how well do I know ASM?". Or even better: "do I know to code in something else?" You haven't posted a snippet of what you're doing so we can understand your level of knowledge. If you'd ask me: I'd find out where the INVENTORY pointer is located (it should be derived from Player, as it there's a Player->Inventory dependency; just like in real life: you're the Player, you have a Backpack; the Backpack holds the items) and go from there. Yes, I'd write my own piece of code (ASM, Lua, ASM+Lua) in CE.
Re: Give all items
I have access to the inventory section and this code just overwrites the items already there and cleans up the lines around it to make sure there isn't residual lines from a longer name. So I've gotten that far, I have a code for give all items (displayed) which just maxes the items out and then I have another code which access the same section to give infinite items. They both work great but I imagine that most creators don't code it like this for a give all items cheat.
Code: Select all
[ENABLE]
aobscanmodule(itemsMenu,ffxiiiimg.exe,5E 5B C2 04 00 CC CC CC CC CC CC CC CC CC CC 56 8B F1 8D)
alloc(itemsMenu_newmem,$1000)
label(itemsMenu_code)
label(itemsMenu_return)
label(giveAllItems)
label(bgiveAllItems)
registersymbol(bgiveAllItems)
label(infiniteItems)
label(binfItems_Menu)
registersymbol(binfItems_Menu)
label(itemCheck)
label(maxCheck)
label(nextItem)
label(maxItems)
label(restoreFlags)
itemsMenu_newmem:
giveAllItems:
cmp byte ptr [bgiveAllItems],#1
jne infiniteItems
giveItemCheck:
cmp word ptr [esi],'it'
jne infiniteItems
push esi
//potion
mov dword ptr [esi],705F7469
add esi,4
mov dword ptr [esi],6F69746F
add esi,4
mov dword ptr [esi],0000006E
add esi,4
mov dword ptr [esi],00000000
add esi,4
mov dword ptr [esi],00000063
add esi,4
mov dword ptr [esi],00000000
//phoenix down
add esi,4
mov dword ptr [esi],705F7469
add esi,4
mov dword ptr [esi],786E6568
add esi,4
mov dword ptr [esi],006C6174
add esi,4
mov dword ptr [esi],00000000
add esi,4
mov dword ptr [esi],00000063
add esi,4
mov dword ptr [esi],00000001
//elixir
add esi,4
mov dword ptr [esi],655F7469
add esi,4
mov dword ptr [esi],6978696C
add esi,4
mov dword ptr [esi],00000072
add esi,4
mov dword ptr [esi],00000000
add esi,4
mov dword ptr [esi],00000063
add esi,4
mov dword ptr [esi],00000002
//....this goes on for the total amount of 14 items
mov [bgiveAllItems],#0
restoreFlags:
pop esi
itemsMenu_code:
pop esi
pop ebx
ret 0004
jmp itemsMenu_return
dd 0
bgiveAllItems:
db 0
itemsMenu:
jmp itemsMenu_newmem
itemsMenu_return:
registersymbol(itemsMenu)
[DISABLE]
itemsMenu:
db 5E 5B C2 04 00
unregistersymbol(itemsMenu)
unregistersymbol(bgiveAllItems)
dealloc(itemsMenu_newmem)
Re: Give all items
Considering the ease of the inventory system here:
If you have a large enough code cave to work with, you can manually write out a static "Inventory" in bytes then iterate x times, reading & writing however many bytes at a time you want, until you've hit the end. The length of your loop would depend on the length of bytes used per cycle and how long the inventory needs to be, really.
Alternatively, try Lua. You can just define a table in lua, with each index containing 8bytes and just iterate through that, using writeBytes at a symbol+offset to the inventory.
If you have a large enough code cave to work with, you can manually write out a static "Inventory" in bytes then iterate x times, reading & writing however many bytes at a time you want, until you've hit the end. The length of your loop would depend on the length of bytes used per cycle and how long the inventory needs to be, really.
Alternatively, try Lua. You can just define a table in lua, with each index containing 8bytes and just iterate through that, using writeBytes at a symbol+offset to the inventory.
Re: Give all items
I appreciate the help, I don't know lua and looking it over, I'm not going to be able to just use it to throw my code together and learn as I go. So, I have dug deeper into asm and I have found a list of items the game stores. The value changes every reload though, so I compared out the section I need and created a symbol that I have displayed in the cheat table.EpicBirdi wrote: ↑Sun Sep 26, 2021 5:49 amConsidering the ease of the inventory system here:
If you have a large enough code cave to work with, you can manually write out a static "Inventory" in bytes then iterate x times, reading & writing however many bytes at a time you want, until you've hit the end. The length of your loop would depend on the length of bytes used per cycle and how long the inventory needs to be, really.
Alternatively, try Lua. You can just define a table in lua, with each index containing 8bytes and just iterate through that, using writeBytes at a symbol+offset to the inventory.
Create Symbol from game's list:
Code: Select all
[ENABLE]
aobscanmodule(item_Base,ffxiiiimg.exe,8B 56 08 C1 E8 18 88 44 24 08 8B C1 C1 E8 10 88 44)
alloc(newmem,$100)
label(code)
label(return)
label(itemBase)
registersymbol(itemBase)
newmem:
cmp dword ptr [esi],'it_p'
jne code
cmp dword ptr [esi+4],'otio'
jne code
cmp byte ptr [esi+8],'n'
jne code
cmp dword ptr [esi+20],'it_p'
jne code
mov dword ptr [itemBase],esi
code:
mov edx,[esi+08]
shr eax,18
jmp return
itemBase:
dd 0
item_Base:
jmp newmem
nop
return:
registersymbol(item_Base)
[DISABLE]
item_Base:
db 8B 56 08 C1 E8 18
unregistersymbol(item_Base)
unregistersymbol(itemBase)
dealloc(newmem)
Loop through in game inventory using game's list with created symbol:
Code: Select all
[ENABLE]
aobscanmodule(itemsMenu,ffxiiiimg.exe,5E 5B C2 04 00 CC CC CC CC CC CC CC CC CC CC 56 8B F1 8D)
alloc(itemsMenu_newmem,$1000)
label(itemsMenu_code)
label(itemsMenu_return)
label(giveAllCheck)
label(giveAllItems)
label(itemsLoop)
label(bgiveAllItems)
registersymbol(bgiveAllItems)
label(giveAllMaterials)
label(bgiveAllMaterials)
registersymbol(bgiveAllMaterials)
label(infiniteItems)
label(binfItems_Menu)
registersymbol(binfItems_Menu)
label(itemCheck)
label(maxCheck)
label(nextItem)
label(maxItems)
label(temp)
label(restoreFlags)
////////////////////////////////////////////////////////////////////////////////
itemsMenu_newmem:
giveAllCheck:
cmp byte ptr [bgiveAllItems],#1
je giveAllItems
cmp byte ptr [bgiveAllMaterials],#1
je giveAllMaterials
jmp itemsMenu_code
///////////////////////////////////////////
giveAllItems:
cmp word ptr [esi],'it'
jne giveAllCheck
push ebx
push eax
push esi
push ecx
mov ebx,[itemBase]
cmp dword ptr [ebx],'it_p'
jne restoreFlags
sub ebx,192
mov ecx,#14
itemsLoop:
mov eax,[ebx]
mov [esi],eax
add ebx,4
mov eax,[ebx]
mov [esi+4],eax
add ebx,4
mov eax,[ebx]
mov [esi+8],eax
add ebx,4
mov eax,[ebx]
mov [esi+C],ebx
mov [esi+10],#99
add ebx,14
add esi,18
//add ebx,20
//add esi,C
loop itemsLoop
mov [bgiveAllItems],#0
pop ecx
pop esi
pop eax
pop ebx
jmp giveAllCheck
///////////////////////////////////////////
infiniteItems:
cmp byte ptr [binfItems_Menu],#1
jne itemsMenu_code
itemCheck:
cmp word ptr [esi],'it'
jne itemsMenu_code
push esi
add esi,10
maxCheck:
cmp word ptr [esi],#0
jz restoreFlags
cmp word ptr [esi],#99
je nextItem
maxItems:
mov word ptr [esi],#99
nextItem:
add esi,18
jmp maxCheck
call restoreFlags
jmp itemsMenu_code
///////////////////////////////////////////
restoreFlags:
pop ecx
pop esi
pop eax
pop ebx
ret
///////////////////////////////////////////
itemsMenu_code:
pop esi
pop ebx
ret 0004
jmp itemsMenu_return
dd 0
temp:
dd 0
bgiveAllItems:
db 0
bgiveAllMaterials:
db 0
binfItems_Menu:
db 0
itemsMenu:
jmp itemsMenu_newmem
itemsMenu_return:
registersymbol(itemsMenu)
[DISABLE]
itemsMenu:
db 5E 5B C2 04 00
unregistersymbol(itemsMenu)
unregistersymbol(temp)
unregistersymbol(bgiveAllItems)
unregistersymbol(bgiveAllMaterials)
unregistersymbol(binfItems_Menu)
dealloc(itemsMenu_newmem)
just want to finish this cheat table off with this give all cheat and then I want to go learn lua, as I think it will be a major player in future cheat tables I create.
Re: Give all items
use a pointer or aobscan and write bytes directly into your memory
here are some examples of how i would do it
here are some examples of how i would do it
Code: Select all
ItemInject+10000: //potion
db 70 5F 74 69 6F 69 74 6F 00 00 00 6E 00 00 00 00 00 00 00 63 00 00 00 00
ItemInject+10024: //phoenix down
db 70 5F 74 69 78 6E 65 68 00 6C 61 74 00 00 00 00 00 00 00 63 00 00 00 01
ItemInject+10048: //elixir
db 65 5F 74 69 69 78 69 6C 00 00 00 72 00 00 00 00 00 00 00 63 00 00 00 02
or
ItemsInject+10000://potion,phoenix down,elixir....... (write everything at once)
db 70 5F 74 69 6F 69 74 6F 00 00 00 6E 00 00 00 00 00 00 00 63 00 00 00 00 70 5F 74 69 78 6E 65 68 00 6C 61 74 00 00 00 00 00 00 00 63 00 00 00 01 65 5F 74 69 69 78 69 6C 00 00 00 72 00 00 00 00 00 00 00 63 00 00 00 02
or lua
--//potion
writeBytes("Item+10000", 0x70, 0x5F, 0x74, 0x69, 0x6F, 0x69, 0x74, 0x6F, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00)
Re: Give all items
I appreciate all the help everyone, especially EpicBirdi, for the extra help through discord.
So instead of actually doing like you all were recommending, what I was working towards and got working was this...
I defined a label and symbol to use:
I then, in another aobscan array, used a code that accessed a part of memory that referenced a complete list that the game already stores in memory. Then compare out and store in my setup symbol:
I then have it put the symbol into a register. Since the symbol is stored as the address location, I then have a reference point to every item in the game.
I then have it loop through the list and pasting the address. It gets the value of ebx (which is my symbol) is pointed at and stores it into eax and then moves it into the value of what esi (which is the inventory location) is pointed at.
I then just have it go through each time of inventory item. Items, materials, and key items etc...
So this way works...sort of.
The issue this will cause among general users of it. Will be that the base address, that access's the games stored item's list, is only updated on inventory entry. So I made a couple headers and checks to prevent that as best as possible, but if they don't read they will crash there game by turning the codes on before updating the base address because they are both updated and accessed when you enter the inventory screen.
So although this works, the way you all recommend is better, it may cause a larger file size but eliminates user error.
If the game had a better way to access its own stored item list, then this way would work fine, but it doesn't. So if the user doesn't listen and turns on the base address and the give all at the same time, then it will crash.
So instead of actually doing like you all were recommending, what I was working towards and got working was this...
I defined a label and symbol to use:
Code: Select all
label(giveAllBase)
registersymbol(giveAllBase)
Code: Select all
newmem:
cmp dword ptr [esi],'it_p'
jne code
cmp dword ptr [esi+4],'otio'
jne code
cmp byte ptr [esi+8],'n'
jne code
cmp dword ptr [esi+20],'it_p'
jne code
mov dword ptr [giveAllBase],esi
Code: Select all
giveAllItems:
cmp byte ptr [bgiveAllItems],#1
jne giveAllMaterials
push ebx
push eax
push esi
push ecx
mov ebx,[giveAllBase]
sub ebx,#192
mov ecx,#14
Code: Select all
itemsLoop:
mov eax,[ebx]
mov [esi],eax
add ebx,4
mov eax,[ebx]
mov [esi+4],eax
add ebx,4
mov eax,[ebx]
mov [esi+8],eax
add ebx,4
mov eax,[ebx]
mov [esi+C],eax
mov [esi+10],#99
add ebx,14
add esi,18
loop itemsLoop
So this way works...sort of.
The issue this will cause among general users of it. Will be that the base address, that access's the games stored item's list, is only updated on inventory entry. So I made a couple headers and checks to prevent that as best as possible, but if they don't read they will crash there game by turning the codes on before updating the base address because they are both updated and accessed when you enter the inventory screen.
So although this works, the way you all recommend is better, it may cause a larger file size but eliminates user error.
If the game had a better way to access its own stored item list, then this way would work fine, but it doesn't. So if the user doesn't listen and turns on the base address and the give all at the same time, then it will crash.
Who is online
Users browsing this forum: No registered users