Hacking Survivalist: Invisible Strain help

Anything Cheat Engine related, bugs, suggestions, helping others, etc..
Post Reply
Sigan
Expert Cheater
Expert Cheater
Posts: 267
Joined: Fri May 26, 2017 1:23 am
Reputation: 124

Hacking Survivalist: Invisible Strain help

Post by Sigan »

Game: Survivalist: Invisible Strain

I've written a table for the game, and it's posted here: viewtopic.php?t=12733 (I don't know how to link to the specific post, so scroll down a little)

In the table, I routinely desire to reference my specific communityID. That is, if I want to make a script for no bloodloss, I want it to only affect my community. In the table, the _community variable is a global variable established elsewhere. It's set to always refer to my community's, "uniqueID". So, if the community being referenced at the specific moment in the script is different than my community, it will move on and just do the normal code rather than injecting my changes.
The first way I learned how to make this check is like this:

...
label(noBloodLoss)
label(cleanUp)
label(code)
label(return)

newmem:
push rcx
push rdx
mov rcx,[rsi+290] //community
mov rdx,[rcx+98] //uniqueID
cmp [_community],rdx
jne cleanUp
movss xmm5,[noBloodLoss]
cleanUp:
pop rdx
pop rcx
code:
...
noBloodLoss:
dd (float)0
...
It's injected in the Character method, and the offset for the community is +290 from that method. Then, from within the community method, the uniqueID is offset +98. I'm a bit unsure if I have to push two registers to accomplish this reference, but that's a side question.
Which is, could I do this, instead, and have it work just fine:

...
newmem:
push rcx
mov rcx,[rsi+290] //community
mov rcx,[rcx+98] //uniqueID
cmp [_community],rcx
jne cleanUp
movss xmm5,[noBloodLoss]
cleanUp:
pop rcx
code:
...
Regardless to the answer to that side question, this is all fairly straight-forward. The offset references a method, and then the second offset is a variable within that method.

My problem comes up whenever I want to reference a list. Like, when the offset is listed in the mono dissector as:
Spoiler
290 : Community (type: Community)
I have no problem referring to it. I'm unsure how to reference things in lists, though. Like, for instance, in the CropsManager method, offset +10 is listed like this:
Spoiler

10 : AllCrops (type: System.Collections.Generic.List<PlantableCrop>)
In PlantableCrop is the offset to calculate current moisture in the plant. If I go to that method, and inject in a good location like the Update method, I can make it so that all crops across the map have full moisture all the time and never need to be watered. But, I don't know how to do the cmp for my community, so that it only affects my community rather than all crops across the map.

So that's my question. How can I do this check? Many people might suggest using lua, which is a completely foreign language to me, but I'm asking a question to learn the answers. I'm not sure that I'm ready to learn lua, or the technique used in lua to easily dissect the list, but I'm open to recommendations. Ideally, I'd like to figure out how to do this using assembly, which I'm much more familiar with even though I'm still an elementary student in regards to it. As well, while I don't know how to reference my community from this method, I also don't really know how to reference the moisture level from the CropsManager method, since it's a list.
This won't work

push rdx
mov rdx,[rax+10] //offset for PlantableCrop list
mov [rdx+60],(float)10 //offset for currentMoistureLevel
pop rdx
And above that I would need the line comparing my community to the one that plant belongs in.

I'm in way over my head here, and I'd like some help if I can get it.

GreenHouse
Expert Cheater
Expert Cheater
Posts: 857
Joined: Fri Oct 12, 2018 10:25 pm
Reputation: 889

Re: This is complicated to me

Post by GreenHouse »

I would say that we're missing quite a bit of information here to be able to properly help. But If I understood properly...
If AllCrops is a reference in the same Class as Community is, you can compare that the same way that you did on the other scripts, then get into AllCrops and set the MoistureLevel. If not, check which variables PlantableCrop does have and the registers from Update, and if one of them points to community, then compare with that, and do the same.
Also, I can't know just with what I have, but AllCrops seems to be an Array, so it wouldn't just be:

Code: Select all

mov rdx,[rax+10]
mov [rdx+60],(float)10
The array has more levels than just that. So generically it would be:

Code: Select all

mov rdx,[rax+10] //Move the AllCrops field
//Here [rdx+18] would be the size of the array which you can use for a loop
mov rdx,[rdx+10] //Get inside the array
mov rdx,[rdx+20] //This is the first element in the array ( And each element from here would be +8, so +28 +30 +38 +40... Up to the array size. )
mov [rdx+60],(float)10 //And inside it you can set the MoistureLevel
If everything that accesses the moisture, doesn't have any reference in the Class or in the registers which includes the community or similar, then you'll need to do that. Do a loop, and keep setting the moisture. Or just find a workaround or different way to approach it.

Sigan
Expert Cheater
Expert Cheater
Posts: 267
Joined: Fri May 26, 2017 1:23 am
Reputation: 124

Re: This is complicated to me

Post by Sigan »

GreenHouse wrote:
Sat Jan 15, 2022 4:34 pm
I would say that we're missing quite a bit of information here to be able to properly help. But If I understood properly...
Probably an understatement. You're getting this information through a weak medium - me. I'm limited in my understanding of the terms, so it's quite possible I'm making it more difficult than it needs to be. For that, I apologize.
GreenHouse wrote:
Sat Jan 15, 2022 4:34 pm
If AllCrops is a reference in the same Class as Community is...
It's totally not. It's nowhere near it in any part of any structure.
GreenHouse wrote:
Sat Jan 15, 2022 4:34 pm
If not, check which variables PlantableCrop does have and the registers from Update, and if one of them points to community, then compare with that, and do the same.
I'm working backwards. PlantableCrop is referenced by the CropsManager. CropsManager is referenced by Session. Session references CommunityManager, and CommunityManager references PlayerCommunity, which would be where I could make a comparison. But... I don't think the crops are owned by any specific community. I think they're just treated as plants on the map, and if a member of a community waters them, great. If not, they just die off. Also, "Moisture," may be a separate way to keep the crops watered. I believe I saw another way to water them, but this was just the first one I found that I could change and make a difference with.
GreenHouse wrote:
Sat Jan 15, 2022 4:34 pm
Also, I can't know just with what I have, but AllCrops seems to be an Array, so it wouldn't just be:

Code: Select all

mov rdx,[rax+10]
mov [rdx+60],(float)10
The array has more levels than just that. So generically it would be:

Code: Select all

mov rdx,[rax+10] //Move the AllCrops field
//Here [rdx+18] would be the size of the array which you can use for a loop
mov rdx,[rdx+10] //Get inside the array
mov rdx,[rdx+20] //This is the first element in the array ( And each element from here would be +8, so +28 +30 +38 +40... Up to the array size. )
mov [rdx+60],(float)10 //And inside it you can set the MoistureLevel
If everything that accesses the moisture, doesn't have any reference in the Class or in the registers which includes the community or similar, then you'll need to do that. Do a loop, and keep setting the moisture. Or just find a workaround or different way to approach it.
I don't understand that array stuff. I don't know how to create a loop in assembly. I think I need to take a completely different approach here. I believe I could find the time it was last watered, and check if it was watered by a member of my community and, if so, then set the crop to be just fully grown instead of all this stuff.

I was more interested in exactly what you started to explain with the array. I run into these pretty often and haven't found any tutorials on how to deal with them in cheat engine. I've watched a few Stephen Chapman videos on YouTube (aka SneakyMofo) on how to use the mono features, and those were really educational and helpful. So, I'm using this example to maybe learn how to deal with these things.

User avatar
aanpsx
Table Makers
Table Makers
Posts: 207
Joined: Thu Apr 12, 2018 4:53 am
Reputation: 846

Re: Hacking Survivalist: Invisible Strain help

Post by aanpsx »

Hi...
You can try like this for looping

Image

Code: Select all

Newmem_CropsManager:
  mov [_CropsManager],rcx // Main pointer
//==================== Registers
  mov [_CropsManager+8], rax
  mov [_CropsManager+10],rbx
  mov [_CropsManager+18],rcx
  mov [_CropsManager+20],rdx
  mov [_CropsManager+28],rdi
  mov [_CropsManager+30],rsi
  mov [_CropsManager+38], r8
  mov [_CropsManager+40], r9
  mov [_CropsManager+48],r10
  mov [_CropsManager+50],r11
  mov [_CropsManager+58],r12
  mov [_CropsManager+60],r13
  mov [_CropsManager+68],r14
  mov [_CropsManager+70],r15
  mov [_CropsManager+78],rbp
  mov [_CropsManager+80],rsp
//==================== Inject here
  mov rbx,0//set rbx to 0
  mov r15,[rcx+18]//Patches
  test r15,r15
  je Exit_CropsManager
  mov r9,[r15+18]//_size
  test r9,r9
  mov [_CropsManager+90],r9//save current # array of "Patches" (use to cmp)
  //=============
  mov r15,[r15+10]//_items
  test r15,r15
  je Exit_CropsManager
Loop_CropsManager:
  mov rdx,[r15+rbx*8+20]//inside Item[0],[1],--->[# of max array]-->[_CropsManager+90]
  test rdx,rdx
  je Exit_CropsManager
  mov r9,[rdx+10]//CropType
@@://cheat 1 --> no water needed
  cmp1 [_CropsManager+100],0
  je @f
  mov4 [r9+188],fmin//WaterNeededPerDayInFlOz
  //mov dword ptr [r9+188],(float)0
@@:
  inc rbx
  cmp [_CropsManager+90],rbx//cmp # of array with rbx
  je Exit_CropsManager
  jmp Loop_CropsManager
Exit_CropsManager:
  //mov rax, [_CropsManager+8]
  mov rbx,[_CropsManager+10]
  //mov rcx,[_CropsManager+18]
  mov rdx,[_CropsManager+20]
  //mov rdi,[_CropsManager+28]
  //mov rsi,[_CropsManager+30]
  //mov r8, [_CropsManager+38]
  mov r9, [_CropsManager+40]
  //mov r10,[_CropsManager+48]
  //mov r11,[_CropsManager+50]
  //mov r12,[_CropsManager+58]
  //mov r13,[_CropsManager+60]
  //mov r14,[_CropsManager+68]
  mov r15,[_CropsManager+70]
  //mov rbp,[_CropsManager+78]
  //mov rsp,[_CropsManager+80]
Attachments
Survivalist Invisible Strain.CT
EA v128
(54.79 KiB) Downloaded 296 times

Sigan
Expert Cheater
Expert Cheater
Posts: 267
Joined: Fri May 26, 2017 1:23 am
Reputation: 124

Re: Hacking Survivalist: Invisible Strain help

Post by Sigan »

Oh my... it appears there are some who understand this stuff pretty well. Thank for sharing. I'll consider messing with this in my next table. I need to learn what it's doing and why, but it's nice of you to take the time to do that for me (well, for us, the community, actually).

Post Reply

Who is online

Users browsing this forum: No registered users