Introduction[]
In Section (B), we learned about The DtC (Display to Clipboard) Exploit, and wrote our first codes and executed it, but it's just a string printer; meaning we only changed a byte or two, so in this section, we will try to attack our opponent by using %f.
Preparation[]
In most cases in reverse engineering space, we need to dig through thousands of lines, researching, gathering insight on the inner workings of MUGEN (if any) etc. etc., like where the enemy's health is located (These values are stored in Virtual Memory/Addresses), but in the Cheap Community, the community has discovered a LOT of Memory Addresses. To learn more or just browse these addresses, use these 2 links below:
Coding[]
BITS 32
;At first we should get a pointer to MUGEN_GAME_VAR,
;this pointer is located at 0x004B5B4C, so we need use mov instruction,
;and don't forget backup original registers values
pushad ;push all normal registers values to stack
mov eax,[0x004B5B4C]
mov ebp,0 ;this will be used to determine whether the character is ourselves
xor ecx,ecx ;clean counter registers
loopForCharacter:
inc ecx ;increase counter for enumerate player
mov ebx,[eax+ecx*4+0xB750] ;get player basic information pointer
cmp ecx,4;is it player but not a helper?
ja endForPlayer ;finish our attack
cmp ebx,0x004B404A ;is it valid?
jb loopForCharacter ;lower than address which valid addresses are bigger than this normally
cmp dword [ebx+0xC],ebp ;is it our team?
je fixMyData;don't attack myself and fix our data
;normal direct death
mov dword [ebx+0xE24],0 ;set alive to 0
mov dword [ebx+0x160],0 ;set life to 0
mov dword [ebx+0x164],-1 ;set lifeMax to -1(this can't be 0 because of divided by zero exception!
mov dword [ebx+0x168],0 ;set lifeBar to 0
;normal frozen
mov dword [ebx+0x1DC],0 ;set pausemovetime to 0
mov dword [ebx+0x1E0],0 ;set superpausemovetime to 0
mov dword [ebx+0x15C],1 ;set isFrozen to 1
mov dword [eax+0xBC34],ebp ;set our team win
mov dword [eax+0xBC38],1 ;show KO
mov dword [eax+0xBC40],0 ;clean round timer(just like F5)
mov dword [eax+0xBB78+2],0 ;noKo clear
mov dword [eax+0xBB78+1],0 ;roundNotOver clear
jmp loopForCharacter ;find next character
fixMyData:
;normal direct death protection
mov dword [ebx+0xE24],1 ;set alive to 1
mov dword [ebx+0x160],1000 ;set life to 1000
mov dword [ebx+0x164],1000 ;set lifeMax to 1000
mov dword [ebx+0x168],1000 ;set lifeBar to 1000
;normal frozen
mov dword [ebx+0x1DC],0x7FFFFFFF ;set pausemovetime to INT_MAX
mov dword [ebx+0x1E0],0x7FFFFFFF ;set superpausemovetime to INT_MAX
mov dword [ebx+0x15C],0 ;set isFrozen to 0
mov dword [eax+0xBC34],ebp ;set our team win
jmp loopForCharacter ;find next character
endForPlayer:
popad ;pop all normal registers values from stack
mov dword [0x4b48e8],0x496651;fix attack
push 0x00496651 ;return to original function
ret ;jump back
By reading the comments (text after ";") and observe the code structure, we use EBP to determine our who's who, so we should use DtC to modify our code when DtC writing the complied codes to memory.
compile this code and use C32Asm to open the result(.bin file), we can find the byte codes of "mov ebp,0":BD 00 00 00 00. then we can move our cursor to front of target byte codes:


189 is here
We can notice that the offset of "BD 00 00 00 00" is 6(at the bottom of C32Asm windows),then we use calc.exe to convert 0xBD to decimal number:189, and find this in converted DtC controllers.
and then find the next byte of 189, and we need overwrite 0 to our team side. in this case, we can use normal trigger to get(teamSide)
and use the previous knowledge, we can complete it with DtC and %f Exploit, then we can run the game.

We success!