Create a Delphi Dll and load it with DllMain - forms

Friends
Im with a little problem. Im trying to create a delphi Dll with a form in RAD Studio, but i don't know how to make it load with DllMain. I want to inject this Dll in a third-party process at runtime after.
I created the Dll project with the form without problems, but i can't find nothing good related to "how to load it with DllMain", or at least the tutorials/things i found doesn't helped me (or i'm just dumb).
Can someone help me? Give me some hint or a site/video where i can learn it?
I really appreciate your time guys! =)

You could use assembly to inject the ebp-based stack into some variables. Here is an example:
library Project1;
uses
System.SysUtils,
Windows,
System.Classes;
var
hInstDLL: THandle;
fdwReason: DWORD;
lpReserved: DWORD;
begin
asm
push eax; // Save the current eax
mov eax, [ebp+$8] // Put into eax the first argument of the current function (DLLMain)
mov [hInstDLL], eax; // Put into hInstDLL this argument
mov eax, [ebp+$c] // Load into eax the second argument
mov [fdwReason], eax; // Save to fdwReason
mov eax, [ebp+$10] // Put into eax the last argument
mov [lpReserved], eax; // Put into lpReserved (unnecessery)
pop eax; // Restore the original eax value
end;
if fdwReason = 1 {DLL_PROCESS_ATTACH} then
begin
// Do your stuff;
end;
end.

Related

Understanding STMicro Reset Handler example code for STM32

The example Reset Handler code provided by STMicro for STM32 (in my case it is for STM32H753) is the following:
Reset_Handler:
ldr sp, =_estack
movs r1, #0
b LoopCopyDataInit
...
I don't understand the first instruction, that sets the stack pointer.
Indeed the Vector Table is defined as follows:
This means that the Stack Pointer is set by the CPU from the first word in the Vector Table. This is confirmed by debug (when breaking before executing the very first instruction of the Reset Handler, the SP is set properly).
Is there a reason to keep this instruction ldr sp, =_estack in thr Reset Handler ?
The Vector table contains on its first position the initial stack address. But the programmer might want to set another value to it or set up the double stack.
In the linker script you have:
_estack = address ;
and in the very simple startup file:
g_pfnVectors:
.word _estack
.word Reset_Handler
but you can change those values to be different or the ResetHandler is called from the bootloader. Then you need to set the stack pointer to the correct value.

arm cortex m4 xPSR change when branching

I am writing an operating system... I am working on context switching
..
I can switch the kernel into user program and go back. but SVC call seems not work well.
syscall:
svc SYSCALL_SVC_NUMBER
bx lr
when calling svc it trigger interrupt, I can see the control flow go back to kernel. The hard fault arise when it gets back to user program.
around here
--> bx lr
I've checked that all the registers are correctly loaded, except that xPSR lacks of thumb bit. That's why the hard fault comes.
But I have no idea why xPSR is clear to zero...
.global activate
activate:
/* save kernel state in ip register */
mrs ip, psr
push {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
/* switch to process stack */
msr psp, r0
mov ip, #2
msr control, ip
ldr ip, [sp, #0x38]
msr psr_nzcvq, ip
/* load user state */
pop {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
add sp, #0x8
ldr ip, [sp, #-0x8]
/* this line can branch correctly */
bx ip
Ahh, yes, you are right, but you dont need to modify anything at the same time.
Using this code for example
mov r1,#0x22
mov r2,#0x33
mov r3,#0x44
mov r0,#0x55
mov r12,r0
mov r0,#0x66
mov r14,r0
mov r0,#0x11
svc #1
The stack looks like this when it hits the svc handler
Fairly certain this is documented
20000FD4 FFFFFFF9 return address
20000FD8 00000011 r0
20000FDC 00000022 r1
20000FE0 00000033 r2
20000FE4 00000044 r3
20000FE8 00000055 r12
20000FEC 00000066 r14
20000FF0 0100009E r15
20000FF4 21000000 xPSR
On an exception on a cortex-m they behave in hardware in a way that can call a C function directly per their calling convention. Understand that the program counter itself has an lsbit of 0, the lsbit of 1 thing is for BX, BLX and POP, it is used by those instructions to determine ARM or THUMB mode, the bit is stripped then used as the PC.
The return from an SVC can/should look like the above. if you want to use svc or any other interrupt to do a context switch you need to build the stack to match.
there is a bit of a chicken and egg problem of course, for each thread you build a stack image like the above
20000FD4 FFFFFFF9
20000FD8 00000011
20000FDC 00000022
20000FE0 00000033
20000FE4 00000044
20000FE8 00000055
20000FEC 00000066
20000FF0 01001234
20000FF4 21000000
but you can put dont cares in the registers except for the pc which you set to the entry point of your thread. with the lsbit not set. Also you need some structure where you keep the state of the other registers.
then when you context switch you save the registers other than the above in a structure somewhere, which includes the sp, you then fill in those registers from the next thread including its sp. then you bx lr to return.
there is a little more to it than that, see atomthreads or chibios or other open source, functional OS.
You are correct the address that was interrupted or in this case the address after the svc, the program counter, is on the stack without the lsbit set, but at the same time that is correct. The actual lr used to return from the exception (svc or timer interrupt or whatever) is the special "exception return" 0xFFFFFFxx which has the lsbit set.

Cortex-A5 unaligned access exception

I have some question for Cortex-A5 unaligned access exception
Basic System information blow
I and D cache enabled.
Disabled MMU.
Firmware base
In developing the DMA driver code I wrote the following C code.
UINT32 DMA_InstMOV(UINT8 *buf, tENC_RD rd, UINT32 val)
{
buf[0] = CMD_DMAMOV;
buf[1] = rd;
*((UINT32 *)&buf[2]) = val; // this line is exception occur
return SIZE_DMAMOV;
}
Dissamber the code above to check them as follows
DMA_InstMOV
0x00000bf8: e1a03000 .0.. MOV r3,r0
0x00000bfc: e3a000bc .... MOV r0,#0xbc
0x00000c00: e5c30000 .... STRB r0,[r3,#0]
0x00000c04: e5c31001 .... STRB r1,[r3,#1]
0x00000c08: e5832002 . .. STR r2,[r3,#2]
0x00000c0c: e3a00006 .... MOV r0,#6
0x00000c10: e12fff1e ../. BX lr
R3 Value is 0x08040000
STR instruction is executed with unaligned address Exception(Data Abort) occurs.
Cortex A5 is not support unaligned access?
In DDI0406C_b_arm_architecture_reference_manual.pdf(Table A3-1 Alignment requirements of load/store instructions)
LDM, STR is not support unaligned access.
So Data Exception occurs.
But I still have some question
This drivers code is working good in Cortex-R4 core. It didn’t have any problem.
Disassebly code is same.
This is even more confusing
Many linux drivers also use the above code.
If the MMU is turned on, which would solve this problem?
Let’s me know what’s worng for me?
You need to enable MMU for making an unaligned access in cortex A5. Also make sure the bitfield "A" in SCTLR register is set to 0 to ensure that strict alignment fault is disabled
As I see it, you can't do what you are trying if buf is 32-bit aligned.
The compiler doesn't know how buf is aligned, so it assumes you know what you are doing. If you ask for a 32-bit write (by doing something like *((UINT32 *)&buf[2])) then the compilers assumes it is a valid thing to do. It therefore generates a STR instruction, which is only valid for aligned stores. Hence the fault - as buf is 32-bit aligned (as you state), buf[2] is clearly not.
I have no idea why the Cortex-R4 experience should be different, as far as I can tell it operates with the same instruction set and alignment rules as the A5 (but I could be wrong). Maybe you got lucky and your bufs were unaligned such that buf[2] was 32-bit aligned.

change local stack variable value

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.

finding type of function arguments with gdb

I'm working on reversing some private functions in CoreTelephony for iPhone. Reversing objC is no biggie, but I can find the type of the arguments for example of _CTServerConnectionCreate.
if I break at _CTServerConnectionCreate and use "info args" it will fail because no symbol table info is available :(
If I switch to that frame and use "info frame" I get
Stack level 0, frame at 0x2fffe94c:
pc = 0x3380807c in _CTServerConnectionCreate; saved pc 0x15fe0
called by frame at 0x2fffe9d8
Arglist at 0x2fffe944, args:
Locals at 0x2fffe944, Saved registers:
r4 at 0x2fffe938, r5 at 0x2fffe93c, r6 at 0x2fffe940, r7 at 0x2fffe944,
r8 at 0x2fffe934, lr at 0x2fffe948, pc at 0x2fffe948
but that doesn't help me much.
Do you have any idea about finding the type of function arguments?