Jump to content

assembler help?


j'ordos

Recommended Posts

Hello everyone,

 

I've been doing some xcom apocalypse modding again after a long break. One thing I've been trying to do is to reduce the number of cleanup missions by preventing the aliens from spreading too often. What I'd like to do is to only allow aliens to spread to a nearby building if their number is greater than 36 (which, IIRC, is the maximum number of aliens on a tactical map). I've found the relevant code using IDA but unfortunately I don't really understand asm all that well and I've been unable to figure out the formula it's using. If anyone could help me out that'd be great! smile.png

 

loc_6F82C: ; Logical Exclusive OR
xor edx, edx
mov eax, dword_E0D0C[ebx]
mov dl, [ecx+0D4h] ; aliens in buildings
add eax, edi ; Add
imul edx, eax ; Signed Multiply
mov [esp+54h+var_1C], 64h
mov eax, edx
sar edx, 1Fh ; Shift Arithmetic Right
idiv [esp+54h+var_1C] ; Signed Divide
add ebx, 4 ; Add
inc ecx ; Increment by 1
add esi, eax ; Add
mov [esp+ebx+54h+var_58], eax
cmp ebx, 38h ; loop through each alien type
jnz short loc_6F82C ; Jump if Not Zero (ZF=0)

So this piece if code loops through all the alien types in a given building.it starts by setting edx to 0, then it puts some kind of modifier value for the current alien type in eax. The actual # of aliens of the current type is then put in dl (edi). And then all kinds of mysterious math takes place smile.png . The modifier value in eax lies around 30 for most alien types, some aliens don't count for anything (value set to 0) - for example chrysali. Once ebx reaches 38 (increases by 4 each step) the loop ends and the code jumps here:

cmp esi, 3 ; total number of aliens in building??
jl abortspread? ; Jump if Less (SF!=OF)

so if esi is smaller then 3 the aliens stay put, otherwise they (may?) spread.

 

edit: ok nevermind, I managed to figure it out myself

Link to comment
Share on other sites

OK, I've got another question. This time I'm trying to modify a small amount of code so that when a UFO drops aliens the building is marked on the overhead map (tired of constantly having to monitor the troop transports). For this I need to overwrite another piece of code though. I found some that I don't need in a sub that adds the aliens to the building: for each alien type there is a 5% chance it will be placed in the next building instead. Since I'm trying to reduce the number of cleanup missions as well I figured I should replace that code. To mark the building I need to edit a var in the building data struct which is loaded after the code I intend to overwrite, so I add the new code in another place than the code I'm removing, but within the same sub. Unfortunately the game crashes when I do this, dosbox gives me an error 'exit to error: illegal jump descriptor type 0' or something like that. Anyone an idea on what could be the cause?

 

this is the original sub I'm patching:

cseg01:0005FDDC add_aliens_build proc near ; CODE XREF: UFO_drop?+59Fp
cseg01:0005FDDC 51 push ecx
cseg01:0005FDDD 56 push esi
cseg01:0005FDDE 89 C1 mov ecx, eax
cseg01:0005FDE0 0F BF C2 movsx eax, dx ; Move with Sign-Extend
cseg01:0005FDE3 E8 74 F3 FF FF call check_bldisxcombase? ; Call Procedure
cseg01:0005FDE8 0F BF F0 movsx esi, ax ; Move with Sign-Extend
cseg01:0005FDEB 83 FE FF cmp esi, 0FFFFFFFFh ; Compare Two Operands
cseg01:0005FDEE 74 1F jz short loc_5FE0F ; Jump if Zero (ZF=1) this jump address has to be modified because some bytes are removed from the code between here and loc_5FE0F, or the jump can be removed entirely
cseg01:0005FDF0 B8 64 00 00 00 mov eax, 64h ;The following code is what I'd like to remove

cseg01:0005FDF5 E8 DE D3 FF FF call randomize ; Call Procedure
cseg01:0005FDFA 66 3D 05 00 cmp ax, 5 ; Compare Two Operands
cseg01:0005FDFE 73 0F jnb short loc_5FE0F ; Jump if Not Below (CF=0)
cseg01:0005FE00 69 F6 BE 02 00+ imul esi, 2BEh ; Signed Multiply
cseg01:0005FE06 66 C7 86 EA 96+ mov word_D96EA[esi], 1
cseg01:0005FE0F
cseg01:0005FE0F loc_5FE0F: ; CODE XREF: add_aliens_build+12j This is the code that actually adds the aliens to a building, here I want to patch in an instruction that marks the building on the map
cseg01:0005FE0F ; add_aliens_build+22j
cseg01:0005FE0F 0F BF D2 movsx edx, dx ; Move with Sign-Extend
cseg01:0005FE12 8D 04 D5 00 00+ lea eax, ds:0[edx*8] ; Load Effective Address
cseg01:0005FE19 29 D0 sub eax, edx ; Integer Subtraction
cseg01:0005FE1B C1 E0 04 shl eax, 4 ; Shift Logical Left
cseg01:0005FE1E 01 C2 add edx, eax ; Add
cseg01:0005FE20 A1 6C 27 18 00 mov eax, save_build
cseg01:0005FE25 01 D2 add edx, edx ; Add
cseg01:0005FE27 01 D0 add eax, edx ; Add
cseg01:0005FE29 0F BF D1 movsx edx, cx ; Move with Sign-Extend
cseg01:0005FE2C 01 D0 add eax, edx ; Add
cseg01:0005FE2E 31 D2 xor edx, edx ; Logical Exclusive OR
cseg01:0005FE30 0F BF F3 movsx esi, bx ; Move with Sign-Extend
cseg01:0005FE33 8A 90 D4 00 00+ mov dl, [eax+0D4h]
cseg01:0005FE39 01 F2 add edx, esi ; Add
cseg01:0005FE3B 83 FA 64 cmp edx, 64h ; Compare Two Operands
cseg01:0005FE3E 7D 09 jge short loc_5FE49 ; Jump if Greater or Equal (SF=OF)
cseg01:0005FE40 00 98 D4 00 00+ add [eax+0D4h], bl ; Add
cseg01:0005FE46 5E pop esi
cseg01:0005FE47 59 pop ecx
cseg01:0005FE48 C3 retn ; Return Near from Procedure
cseg01:0005FE49 ; ---------------------------------------------------------------------------

Link to comment
Share on other sites

  • 2 weeks later...

You should try to rerun IDA over your new exe and look at the place.

The problem: when you shift a far jump in a fonction, it usually makes the program crash. It's best to avoid shrifting whole parts of the code, use local jumps instead, creating a small "pocket" where you can insert whatever you need.

 

a) delete the code you don't want

b) use jmp to "bridge it"

c) use another jmp to access the (now bridged) pocket

d) at the end of the pocket. jump back

 

------

The case above is complicated since you don't give enough information.

shr dx, 16 is usually used during fraction multiply. It's a bit hard to understand, if you need more info, contact me. hth

Link to comment
Share on other sites

  • 4 weeks later...

You are welcome.

 

In some types of program code, the far jumps are recalculated when the program starts.

This means that the program will, upon start, overwrite given adresses with new "far jump" location. When you move far jump away, the program still tries to overwrite the location and it corrupts your program.

 

IDA, of course, lets you magically see the overwritten code. That is why it can be used to detect the problems. I learned a self-rule to run every changed code through IDA as a routine to prevent bugs.

Link to comment
Share on other sites

  • 3 weeks later...

I took a look at the changed code in IDA (it's a bit of a hassle since I first have to remove a 32bit extender from the exe before IDA can do anything with it) but I can only load it as a binary file. It still disassembled the function I changed though and I couldn't spot anything wrong with it.

I'll post an image of the graph view of the original code and list my edits, maybe you can spot a problem this way smile.png

 

post-3849-0-09818800-1354910008_thumb.png

 

So the first thing I do is edit the jz short_loc etc... to an unconditional jmp. I also deduct two bytes from the address, because I remove two from the code I'm jumping over (so I can add a new jmp to the code following it to the now unused code to do what I want and jump back afterwards, as you suggested). So in hex the code changes from 74 1F to EB 1E. I change the last two bytes before loc_5FE0F to 90 (nop) and run xcom apoc, no problems. However, once I shift the two nop bytes to where I actually want them (somewhere near that mov dl, [eax+0D4h] line) xcom apocalypse starts crashing. I began looking from where exactly in the code the addition of those two bytes started to cause a crash and found it is right after the mov eax, save_build line (marked on the image). If I add two bytes before that code executes xcom runs fine, if I add them after xcom crashes. Is the address for that mov instruction relative? It looked fine in IDA after the change as far as I could tell. Any ideas?

 

EDIT: I figured I could do the jump before the line from where the added code starts to crash xcom and just repeat the instructions in the newly created pocket, there's just enough room for that. Unfortunately xcom still crashes, this time with a different error though. Well actually no error from xcom but dosbox reports the following in the console: Exit to error: CPU_SetSegGeneral: Stack segment zero.

Here's an image of the IDA output of the function after the modification:

post-3849-0-92840700-1354913162_thumb.png

 

edit2: comparing the images I noticed one instruction had fallen off (add edx,eax) , I corrected it but the crash remains the same

Link to comment
Share on other sites

j'ordos, I've looked at it, have some theories, but... I am afraid I need the big picture to help you.There may be 100 causes of a crash, hard to say from a small portion of code, the context is sometimes crucial. Also, I need to see the hexadecimals (how can you work without them displayed in IDA? I never have them off.)

 

Could you upload somewhere the IDA dbases and exe files "just before" and "just after" the change and PM me the place? (No worry, I will delete it afterwards, not really interested in Apocalypse.)

Link to comment
Share on other sites

OK, thanks for trying to help! I uploaded the files here in a rar archive: https://users.telenet...822/apocasm.rar

A few things to note: the old UFO2P.IDB is based on another version of xcom apoc than the one I'm using now - so it doesn't correspond exactly to UFO2P.EXE. If you want I can upload a disassembly of the new exe instead but it won't have anything mapped out. UFO2Pafter.exe and .idb is the one where I made the modification.

The sub I modified is called 'add_aliens_build', I added it to the new database as well (UFO2Pafter.idb) so you can find it easily. The offset when you open the exe's in a hex editor is 794630 (decimal). This is the address for the first jump in the sub (jz short_loc 5FE0F in the original exe and jmp short loc_8A0F1 in the modified exe). Let me know if you need more info!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...