Basically, what I have is a game which has a function MyFunc(), and it's called on 4 places in the game. One of the addresses is 0x10002000, and the bytes are E8 0B 83 01 00.
I'm injecting a DLL, and want to patch that 0xE8 (call) to my own address. When I do it with Cheat Engine's Auto Assembler and write call MYADDRESS, it generates the proper opcode, and proper bytes.
However, if I do it with the DLL, this is what I get:
What I want to achieve is call 74C611CC. So I need to generate the bytes for the opcode to be like I want instead of what is it currently (in the screenshot)
I use this kind of code:
*(BYTE*) dwPatchAddr = 0xE8;
*(DWORD*) (dwPatchAddr + 1) = (DWORD) myFunc;
An e8 instruction is a relative call instruction, not absolute. So the next 4 bytes need to be the difference between the pc when processing this instruction and your target function. So what you want is:
*(BYTE *)dwPatchAddr = 0xE8;
*(DWORD *)(dwPatchAddr + 1) = (DWORD)((char *)myFunc - (char *)(dwPatchAddr + 5));
Note that the PC address used to compute the offset is actually the address of the next instruction after the call (what will also be pushed as the return address).
Related
Looking for help with understanding how to change value in address DS1 (400001). First the click appears to use a 6 digit Modbus so not sure how to deal with the in 2 bytes. I think I read 40001 is the same but do not see how. I am able to receive data and understand the data when the Click PLC is the master. I would like my PC to be the master and change the address.
Here is the data I am sending to the PLC. I am expecting this data to be sent to PLC slave 02 and change the data in DS1 (400001) to the value of zero.
frame(0) = 2 'Slave Address =2
frame(1) = 6 'Mode =6
frame(2) = CByte(40001 / 256) '
frame(3) = CByte(40001 Mod 256) '
frame(4) = 0 '
frame(5) = 0 '
Dim crc As Byte() = CRC(frame) ' Call CRC Calculate.
frame(6) = crc(0) '=59 Error Check Lo
frame(7) = crc(1) '=189 Error Check Hi
SerialPort1.Write(frame, 0, frame.Length)
Realize that Application Layer addressing in Modbus is different than the bytes on the wire. The leading digit in an application layer address (e.g. 4xxxx for Holding Register) is implied in the function code (e.g. Read Holding Register)
So on the wire, you drop the leading 4, and left with an offset of 1-65536 (yes, Application Layer offsets are 1-based). But on the WIRE, they are 0-based, so you then subtact 1 from the offset to get the value 0-65535.
So, sometimes you see Application Modbus HRs like 4001, 40001, or 400001, all referencing the first HR in the device. 5 digit is most common. I do see 4 digit for old RTU devices. I do see a 6 digit every once in a while where the remote device has a ton of memory (or not, like Click).
Realize that a lot of devices are implemented by people who only understand the low level protocol, so when they say something is at address 40001, it may actually be at offset 0x0001, or 0x0000 (the correct offset on the wire). I even saw one implementation that implemented the address 40001 as literally 0x9C41 on the wire (maybe 0x9C40). Yes, 6 digit Application Layer Holding Register 440001.
A program "HelloWorld" running on Mips Interaptive core0 VPE1, including crt0.S (which I wrote), main.c files creates an ELF in which the symbols are relative to 0x0:
0x0 - _core_reset (this is part of crt0.S)
...
0x460 - fw_reset (this is called from main)
...
0x484 - main (this is the main function)
(-) my ELF undergoes stripping of sections to create a binary file of instructions only, starting in _core_reset
(-) the binary image from last step is loaded to virtual address 0xADB00000, which is physical 0x2DB00000
(-) the first problem is that in _core_reset we do:
la t0,main
mtc0 t0,C0_ERRPC //store it as return address
but main has the address relative to 0x0, which causes memory exception,
what I need is main to be in address loaded + (offset relative to zero),
How do I do that? we can say that the address the image is loaded to and run from is constant
I tried to write in the crt0.S file, hardcoded to change the jump to main address:
lui t0, 0xa6b0 /* Assumtion the FW is loaded to 0xa6b00000 */
addiu t0, t0, main
and it worked an I reached main(), but later when tried to call fw_reset() from main, the address of fw_reset() was again relative to 0x0 and I got a memory exception
I tried from the makefile to add that the .text section of ELF will start from the address loaded, but then I get an issue that my image is loaded to:
(value i provide) + (actual loading address) and so it also doesn't work
I expected my code to reach main() and be stuck in the endless while loop, instead I get memory exceptions since the functions are relative to 0x0, while the code is loaded to another address not zero
Using this diagram, I am looking at this instruction to determine what control lines are necessary.
ld x5, 40(x9)
x5 = 0x000000ff
x9 = 0x00000fff
I am curious what control lines (RegWrite, MemRead, MemWrite, MemtoReg, Branch, Zero, ALUSrc) are asserted or set to 1 in order for this instruction to run, and why I understand the parts of the load double instruction to be ld RT, Disp(RA) - but what is required for execution and why? Thank you - resources on these things (that make sense to me) are extremely limited on the internet.
Its a LOAD instruction in which the memory address to be read is calculated by adding 40 to the contents of the register x9, the result is then stored in register x5.
Instruction is writing to registers, therefore assert RegDst and RegWrite
Instruction is required to add 40 to the contents of x5. Set ALUSrc to 1 to select 40 as one of the source.
Assert MemReadas its a memory read. Also set MemtoReg to 1 so that mux will get the data from Memory rather than ALU.
I just need an explanation of how base + offset addressing modes work. Having trouble finding a clear-cut answer for this. (I've been working with the LC-3, not sure if that matters). A simple example would also be helpful.
Thank you!
MOV EAX,[EBP+8]
MOV EBX,[EBP+12]
EBP is the base here (holds the base address) like "00402000" for instance
so the EAX will be loaded with the value in the address [00402000+8] I.e 00402004
Base + Index addressing mode
2 Registers specify the address of an operand in an instruction.
Add the numerical values stored in those registers to get the complete address of an operand.
Ex.
A = 1000
Register A = 1000
Register B = 8
MOV C, [A,B] => C = contents of location A+B
There is a flavor to Base + Indexing addressing called the base + Index + displacement
Displacement = immediate value in the instruction that is added to the Base + Index.
thats what you see in your opcode.
instruction = OPCODE + Operand 1 Register Spec + Operand 2's Base Register Spec + Operand 2's Index Register Spec + Immediate value.
imagine a microprocessor with a 8 bit register space.
so a 16 bit operand may have
4 bit for opcode
3 bit for base register
3 bit for index register
6 bit for immediate displacement.
Thanks,
I believe I have figured out the answer. I'll post it here in case it helps anyone else who has trouble with this. I found the answer hidden deep in the 100 slide powerpoint that my teacher provided XD
This is what happens when performing an LDR using a base register R6 and destination register R2:
MAR<-R6 + IR[5:0]
MDR<-MEM[MAR]
R2<-MDR
Lets say R6 = x3000, IR[5:0] = x5, and R2 = 0 (although this value doesn't matter since it will be loaded with another value at the end)
MAR<-R6 + IR[5:0]
R6 is added to IR[5:0] (which is the offset value in the last six bits of the LDR instruction). The base x3000 (value of R6) has x5 (value of IR[5:0]) added to it, giving us x3005. The MAR (memory address register) now holds x3005.
MDR<-MEM[MAR]
The value in the MAR (x3005) is loaded into the MDR (memory data register).
R2<-MDR
The value in the MDR (x3005) is loaded into R2. R2 now holds the value: x3005.
I hope this question helps those new to addressing modes like I am :)
Thank you all.
Using Windbg/SOS, it possible to change value of a local varible on stack? If so how?
The short answer is: It depends.
Per default local value types are stored on the stack but due to optimization they will often be stored only in registers as needed. Reference types are stored on the heap, with a reference to the instance on the stack (or in a register).
I am going to assume that you're looking to change a local value type. Let's look at a simple example.
[MethodImpl(MethodImplOptions.NoInlining)] // avoid inlining of short method
public static void Method(int x) {
Console.WriteLine("The answer is {0}", x + x);
}
Assuming we set a breakpoint on Method and run until the breakpoint is hit, the stack looks like this:
0:000> !clrstack -a
OS Thread Id: 0x1abc (0)
Child SP IP Call Site
0035f290 003600e0 TestBench2010.Program.Method(Int32)*** WARNING: Unable to verify checksum for C:\workspaces\TestBench2010\TestBench2010\bin\Release\TestBench2010.exe
[C:\workspaces\TestBench2010\TestBench2010\Program.cs # 17]
PARAMETERS:
x (<CLR reg>) = 0x00000002
0035f294 003600a2 TestBench2010.Program.Main(System.String[]) [C:\workspaces\TestBench2010\TestBench2010\Program.cs # 24]
PARAMETERS:
args = <no data>
0035f4c0 636221bb [GCFrame: 0035f4c0]
Notice that the local x is listed as , but it doesn't tell us which register. We could look at the registers and find the one with the value 2, but there could be more than one. Instead let's look at the JIT compiled code for the method.
0:000> !u 001c37f0
Normal JIT generated code
TestBench2010.Program.Method(Int32)
Begin 003600e0, size 32
C:\workspaces\TestBench2010\TestBench2010\Program.cs # 17:
003600e0 55 push ebp
003600e1 8bec mov ebp,esp
003600e3 56 push esi
003600e4 8bf1 mov esi,ecx
*** WARNING: Unable to verify checksum for C:\windows\assembly\NativeImages_v4.0.30319_32\mscorlib\658bbc023e2f4f4e802be9483e988373\mscorlib.ni.dll
003600e6 b9302be004 mov ecx,offset mscorlib_ni+0x322b30 (04e02b30) (MT: System.Int32)
003600eb e8301fe5ff call 001b2020 (JitHelp: CORINFO_HELP_NEWSFAST)
003600f0 8bd0 mov edx,eax
003600f2 03f6 add esi,esi <==== This is x + x
003600f4 897204 mov dword ptr [edx+4],esi
003600f7 8bf2 mov esi,edx
003600f9 e882709d04 call mscorlib_ni+0x257180 (04d37180)(System.Console.get_Out(), mdToken: 060008cd)
003600fe 56 push esi
003600ff 8bc8 mov ecx,eax
00360101 8b1534204c03 mov edx,dword ptr ds:[34C2034h] ("The answer is {0}")
00360107 8b01 mov eax,dword ptr [ecx]
00360109 8b403c mov eax,dword ptr [eax+3Ch]
0036010c ff5018 call dword ptr [eax+18h]
C:\workspaces\TestBench2010\TestBench2010\Program.cs # 18:
0036010f 5e pop esi
00360110 5d pop ebp
00360111 c3 ret
Looking at the code, we see that the only add instruction uses the esi register, so our value is stored here prior to the calculation. Unfortunately, esi doesn't hold the correct value at this point, but looking backwards we find mov esi,ecx. I.e. the value is initially stored in ecx.
To change the value of ecx use the r command. E.g. to set the value to 0x15 do the following:
0:000> r ecx=15
The output of the method is now:
The answer is 42
Please keep in mind that the example above is only one of many possible scenarios. Locals are handled differently depending on debug/release build as well as 32/64 bit. Also, for complex methods it may be a bit harder tracking the exact location of the value.
To change the state of an instance, you have to locate the reference on the stack (e.g. using !clrstack or !dso). Once located you can use the offsets to find the memory, that holds the data and use the e* commands to change the values as needed. Let me know if you want an example for that as well.