zyllos Posted November 15, 2013 Share Posted November 15, 2013 Ya, it seeming not nearly as bad as I thought, initially. Thanks for the resource. Just a quick question, I am going to assume we can't change the signature of a function because the EXE is looking for the return type and parameters involved, thus "rewriting" functions actually just means repurposing the statements within the scope of the function, correct? Or, is it possible to rewrite entire functions? Link to comment Share on other sites More sharing options...
Krazyguy75 Posted November 15, 2013 Share Posted November 15, 2013 We can rewrite entire functions, so long as the function size (in bytes) is unchanged. Link to comment Share on other sites More sharing options...
Amineri Posted November 15, 2013 Share Posted November 15, 2013 We have re-written the entire contents of a function before. Sometimes we totally changing how the function works. Other times we find unused functions (stuff like debug functions, or functions for features that were cut from the released game). Things that can't be done:1) Increase the number of hex bytes inside a function2) Changing the number of type of parameters3) Changing the return value type4) Technically can't add new local variables, but it is possible to re-use local variables from other functions. Care has to be taken with this, however. Also, it's not possible to add a new function to an existing class, or to add new classes to a upk. Link to comment Share on other sites More sharing options...
zyllos Posted November 15, 2013 Share Posted November 15, 2013 We have re-written the entire contents of a function before. Sometimes we totally changing how the function works. Other times we find unused functions (stuff like debug functions, or functions for features that were cut from the released game). Things that can't be done:1) Increase the number of hex bytes inside a function2) Changing the number of type of parameters3) Changing the return value type4) Technically can't add new local variables, but it is possible to re-use local variables from other functions. Care has to be taken with this, however. Also, it's not possible to add a new function to an existing class, or to add new classes to a upk. Ok, so the size of the function must remain the same (thus take up the same virtual space in memory), the signature of the function must stay the same (inputs/outputs), and it's pretty hard to create new local variables within a function? Really, the major problem at this point is what was newly added with EW, what is the new hexes of variables in these classes, and what is the new hex values needed to be placed in the UPK files to get the old functionality back into the new code. Hmm, does the EW discovery thread contain everything that has been determined so far? I think I am going to just start on the next hex edit in the Changes.txt file and determine what is now needed for it to work. Link to comment Share on other sites More sharing options...
Amineri Posted November 15, 2013 Share Posted November 15, 2013 Ok, so the size of the function must remain the same (thus take up the same virtual space in memory), the signature of the function must stay the same (inputs/outputs), and it's pretty hard to create new local variables within a function? Well, the really interesting part is that the memory size of the function does not have to remain the same. Only the file size of the function. This is another interesting 'feature' of hex editing Unreal code. The file size of the hex and the memory size generally are not the same. Some constructions when loaded occupy additional memory space. For example a 00 ## ## ## ## local variable reference is 5 file bytes but 9 memory bytes. Memory size always increases in 4-byte word chunks. I think that this is because the master table where all of the function references are looks them up based on file position. The loader at run-time then maintains pointers to the various functions after they are loaded. Each function has a 48 byte header consisting of 12 4-byte words. The 11th word in the header is the function's memory size. If the function's memory size has changed (without the file size changing, of course), then this value has to be updated to the new value or the game will CTD immediately on launch. All of this is core to how Unreal works, and so is unchanged for the EW expansion. Link to comment Share on other sites More sharing options...
Vampir3 Posted November 15, 2013 Share Posted November 15, 2013 Is this mod compatible with Enemy within ? Link to comment Share on other sites More sharing options...
johnnylump Posted November 15, 2013 Author Share Posted November 15, 2013 @Vampir3 No. Come back in a few months. Link to comment Share on other sites More sharing options...
dubiousintent Posted November 16, 2013 Share Posted November 16, 2013 Ok, so the size of the function must remain the same (thus take up the same virtual space in memory), the signature of the function must stay the same (inputs/outputs), and it's pretty hard to create new local variables within a function? Well, the really interesting part is that the memory size of the function does not have to remain the same. Only the file size of the function. ...I think this sub-thread will be helpful to others getting into modding from a programmer's background, so I've created the wiki article 'Programmers guide to XCOM:EU 2012 modding' from it. -Dubious- Link to comment Share on other sites More sharing options...
zyllos Posted November 16, 2013 Share Posted November 16, 2013 (edited) Ok, so I have a question, again. Sorry about all this, trying to get to a point where I can actually get a successful modification going. If I say I wanted to rewrite the XGFacility_Hanger.DetermineInterceptorStatus function from the series of if statements it is now, to a simple straight up "always equal to a value". According to your previous statements, the function's file byte size has to remain the same size but the virtual size can change, which means the 11th byte can be whatever size it ends up being calculated to, which I am still kinda hung up on how to calculate, but I am taking baby steps right now. Does this mean I have to utilize the if statements and just make them assign the same values so the file byte size of the function stays the same size or is there a technique to place a bunch of "blank" data in there? Maybe I could do bunch of assignment statements to equal the same number of file bytes? Edited November 16, 2013 by zyllos Link to comment Share on other sites More sharing options...
Amineri Posted November 16, 2013 Share Posted November 16, 2013 The answer is the near-magical 0x0B 'null-op' statement. This value does nothing but take up space. It takes 1 file byte and 1 memory byte. Link to comment Share on other sites More sharing options...
Recommended Posts