Jump to content

Am I missing something basic about hex editing?


LeoKian

Recommended Posts

I feel like I have a good grasp of what I should be doing while hex editing, but every time I try to run the game with one of my modified .upk's it CTDs on start up.

 

For reference, I am editing the Long War Mod XComGame.upk->XGUnit.ApplyHPStatPenalties, and even when I make a painfully simple change, it crashes. For example:

 

Changing:

0F 01 C6 C4 00 00 38 44 AB AF 00 A4 C9 00 00 38 3F 26 16 12 20 32 87 00 00 09 00 1D 11 00 00 00 02 1D 11 00 00 16
// m_iBWAimPenalty = int((fPct - float(1)) * class'XGTacticalGameCore'.default.SW_ABDUCTION_SITES);

To:

0F 01 C6 C4 00 00 2C 10
// m_iBWAimPenalty = 16;

And then I pad the end (but before the EOS ) with 0B's to change the filesize back to the original.

 

Am I skipping a step? I reread the wiki a couple of times trying to figure out where I'm going wrong, but no luck. Should I not be changing the file size at all, so that I do my replacement and 0B padding at once?

 

Edit: Tried doing the whole replace at once, and that didn't help either. I'm assuming I don't have to use XSHAPE.bat because Long War already uses modified files?

 

Edit 2: If it's relevant at all, I've also been unable to decomrpess the XComGame.upk for Long War. I just assumed for B14 the .upk came uncompressed. I don't know if that's related, but here's the error I get:

ERROR: Trying to allocate -1672 bytes
appMalloc:size=-1672 <- FArray::Empty:-418 x 4 <- TArray::SerializeSimple <- ReadDependsTable <- UnPackage::UnPackage:XComGame.upk, ver=845/64, game=8000 <- Main

Edit 3: I've been continuing to bang my head against a wall, and it's still not working, but this is what I've discovered so far:

 

1. If I change a single value, XCOM doesn't crash: makes me think I'm resizing the file wrong.

2. The byte size is identical. When I do the view buffer in UE, the offsets are the same, but...

3. The token sizes are different, and in object view the code goes from this:

    if(fPct >= float(1))
    {
        m_iBWAimPenalty = 0;
        m_iBWMobPenalty = 0;
    }
    // End:0x1D5
    else
    {
        m_iBWAimPenalty = int((fPct - float(1)) * class'XGTacticalGameCore'.default.SW_ABDUCTION_SITES);
        m_iBWMobPenalty = int((fPct - float(1)) * class'XGTacticalGameCore'.default.SW_COVER_INCREASE);
    }
    m_aCurrentStats[1] += m_iBWAimPenalty;
    m_aCurrentStats[3] += m_iBWMobPenalty;
    return;    

To this:

    if(fPct >= float(1))
    {
        m_iBWAimPenalty = 0;
        m_iBWMobPenalty = 0;
    }
    // End:0x1D5
    else
    {
        m_iBWAimPenalty = 16;
        m_iBWMobPenalty = int((fPct - float(1)) * class'XGTacticalGameCore'.default.SW_COVER_INCREASE);
        m_aCurrentStats[1] += m_iBWAimPenalty;
        m_aCurrentStats[3] += m_iBWMobPenalty;
        return;
    }    

Edit bajillion: I now suspect that that my issues are coming from a broken Goto statement in the if/else conditional. Instead of padding the end of the function, I tried to pad the section right after my edit but that still doesn't work. This also wouldn't work later, since I'm trying to make that section longer, rather than shorter. I guess I have to manually point the end of that if/else somewhere new? Any resources on how to do that?

 

Edit :c - So the last goto was the one that pointed to 1D5, which according to UE's token view was the start of m_aCurrentStats[1]...I changed the goto so that it would point to the location of that line in my modified file, but still no luck. It just keeps crashing. Probably good that I found that, as I'm sure it would be trouble later on, but I don't think it was my core issue. Now I'm thinking that maybe it's not 1-1 replacement of unused bytes with 0B, since in token view my function goes to 2B0 on the modified file and to 2C0 on the original file. Don't really understand why, but I'll try adding bytes until the two are equal and see how that goes. Can't think of anything else at this point.

 

Edit nope: Shouldn't do that either. Breaks everything. Is bad.

Edited by LeoKian
Link to comment
Share on other sites

One thing you have to quickly learn when hex-editing Unreal Engine is that there are two different sizes used : memory size and file size.

 

File size is the size of the object as it sits within the upk on your disk, and it used (presumably) when extracting different portions of objects.

 

Memory size is how much memory that same object requires when loaded into memory. In general memory size is larger than file size. That's because each reference to a another import/export object is 4 bytes in the bytecode (it's an integer index into the object table / import table), but the reference requires 8 bytes when loaded into memory. Presumably this is for 64-bit support.

 

The code :

0F 01 C6 C4 00 00 38 44 AB AF 00 A4 C9 00 00 38 3F 26 16 12 20 32 87 00 00 09 00 1D 11 00 00 00 02 1D 11 00 00 16
// m_iBWAimPenalty = int((fPct - float(1)) * class'XGTacticalGameCore'.default.SW_ABDUCTION_SITES);

requires 0x3A memory bytes, but only 0x26 file bytes. (Note that the difference between memory and file will always be a multiple of 4.)

 

Figuring out the memory size is not an obvious or trivial thing, but it's important for a couple of reasons:

 

1) In the function header is stored both the function's memory and file size. Changing the memory size requires updating this header value. Having a bad memory size in a header results in a CTD when the game launches.

 

2) All jump offset positions are defined relative to the memory size. As you saw, changing the memory size of the replacement hex results in incorrect jump offset locations.

 

--------------

 

One of the primary features that XMTS and I coded into UPKmodder (the tool we on the Long War team use for coding) is that it automatically parses the hex, highlights various parts, and computes the memory size/position of each line (or portion of a line).

 

Alternatively UE Explorer displays memory size information when it decompiles, which is what I used prior to UPKmodder to figure out memory sizes.

 

 

 

Good luck! ^_^

Link to comment
Share on other sites

Ah, thanks a bunch! It seems I was indeed missing something basic about hex editing. Is there a place I can read up on these sorts of things or is it more just having a familiarity with how Unreal Script works and trying things until one of them works that led to people figuring all this out?

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...