[Solved]Simple DLL inject problem

Just starting out? Need help? Post your questions and find answers here.
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 277
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

[Solved]Simple DLL inject problem

Post by le_magn »

Hi all, I would like to inject a dll, which once inside calls an internal function of the process, so far I have succeeded, the dll is injected(with esternal iniector), the command is executed ok, but after the command is executed the process interface disappears and remains active in the background, any suggestions? p.s. If i remove freememory(*testo) it work ok...
Main process:

Code: Select all

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf

;- Enumerations
Enumeration Window
  #Window_0
EndEnumeration

Enumeration Gadgets
  #Btn_1
  #Edit_1
EndEnumeration

Global Quit

;- Declare
Declare Open_Window_0(X = 0, Y = 0, Width = 320, Height = 180)

Procedure Mia_AddGadgetItem(gadget, Posizione, Stringa.s, acapo = 1)
  AddGadgetItem(gadget, posizione, Stringa)
  SendMessage_(GadgetID(gadget), #EM_SETSEL, $fffffff, $fffffff)
EndProcedure

Procedure Mia_TESTO(TESTO.S)
  Mia_AddGadgetItem(#Edit_1, - 1, TESTO, 1)
EndProcedure

Procedure Open_Window_0(X = 0, Y = 0, Width = 320, Height = 180)
  If OpenWindow(#Window_0, X, Y, Width, Height, "Title", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
    ButtonGadget(#Btn_1, 100, 20, 100, 24, "Button_1")
    EditorGadget(#Edit_1, 0, 60, 320, 120)
    ProcedureReturn #True
  EndIf
EndProcedure

CompilerIf #PB_Compiler_IsMainFile
;- Main Program
  If Open_Window_0()
    
  ;- Event Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Quit = #True
          
        ;-> Event Gadget
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #Btn_1
              Mia_TESTO("TESTO ORIGINALE")
          EndSelect
          
      EndSelect
    Until Quit
  EndIf
CompilerEndIf
DLL:

Code: Select all

ProcedureDLL AttachProcess(Instance)

  ;   MessageRequester("AttachProcess()", Str(GetModuleHandle_("test.exe")))
  Delay(1000)
  testo.s = "testo modificato"
  lun.l = Len(testo)
  *TESTo = AllocateMemory(lun)
  PokeS(*testo, testo, lun)
  *funzione = GetModuleHandle_("test.exe") + $11B2
  ;   CallCFunctionFast(*FUNZIONE, *testo)
  CallFunctionFast(*FUNZIONE, *testo)
  FreeMemory(*testo)
EndProcedure

ProcedureDLL DetachProcess(Instance)
; printN("2")
  
EndProcedure

ProcedureDLL AttachThread(Instance)
; printN("3")
EndProcedure

ProcedureDLL DetachThread(Instance)
; printN("4")
  
EndProcedure
P.S. i want to do this because i want to create dll to inject in a game, for translate the internal strings in other language...
Last edited by le_magn on Sun Jul 14, 2024 10:17 pm, edited 1 time in total.
Image
User avatar
Caronte3D
Addict
Addict
Posts: 1355
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: Simple DLL inject problem

Post by Caronte3D »

le_magn wrote: Wed Jul 03, 2024 5:40 pm ...but after the command is executed the process interface disappears and remains active in the background, any suggestions?
Maybe do *testo Global and change FreeMemory(*testo) to DetachProcess(Instance)?
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 277
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Simple DLL inject problem

Post by le_magn »

Caronte3D wrote: Wed Jul 03, 2024 7:00 pm Maybe do *testo Global and change FreeMemory(*testo) to DetachProcess(Instance)?
Yes it work!!! thank you
Image
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 277
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Simple DLL inject problem

Post by le_magn »

Now a nice big problem has arisen, basically in a 32bit process I can change the call of the original process by putting the address pointing to the call in my dll, for 64bit processes it is not so simple, if I use a small executable to do the test all ok, but using for example the executable of the game I am interested in translating, the address of the function in the dll turns out to be too far away from the main process(it need more than 4 bytes) , in these cases how could be solved? thanks
Image
User avatar
Caronte3D
Addict
Addict
Posts: 1355
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: Simple DLL inject problem

Post by Caronte3D »

PB integers size are 8 bytes if you use a 64 bits compiler
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 277
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Simple DLL inject problem

Post by le_magn »

yes but original function use 5 bytes for call , jmp+address, if i want to call my procedure in dll i need to use more than 8 bytes, if i overwrite the original code i write also to next instructions and program crash, only way i think is to use a intermediate jump to code cave in original process, and write here some instruction to call my procedure... is a bit complicate compared with normal 32bit.

UPDATE: i solved the problem above, but now i have other issue, if i call my procedure and i use original buffer(buffer contain original text passed to my procedure) it work, but if i want to resize this buffer or allocate new buffer i receive error, invalid memory access or other, try allocatememory() and reallocatememory() same problem, any suggestion is appreciated thank you......
Image
Smitis
New User
New User
Posts: 5
Joined: Mon Sep 04, 2023 11:58 am

Re: Simple DLL inject problem

Post by Smitis »

Could there be a mistake in this:
len(testo) - length in symbols
AllocateMemory(lun) - length in bytes
Plus need two more bytes for terminate zero symbol.

It's better to do this:
*testo = AllocateMemory(StringByteLength(testo)+SizeOf(Character))
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 277
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Simple DLL inject problem

Post by le_magn »

Smitis wrote: Tue Jul 09, 2024 9:58 am Could there be a mistake in this:
len(testo) - length in symbols
AllocateMemory(lun) - length in bytes
Plus need two more bytes for terminate zero symbol.

It's better to do this:
*testo = AllocateMemory(StringByteLength(testo)+SizeOf(Character))
Yes you are right, string need to terminate with 00 byte, and lenght need to be calculated in byte, sometimes we make trivial mistakes, thank you
Image
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 277
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Simple DLL inject problem

Post by le_magn »

I have made progress, I am able to divert the original process function to a memory area where I have set up a trampoline(necessary for 64bit) to call my function in the dll, my function is called and 3 parameters are passed, from my function I am able to read these parameters, and so far so good, but here the headaches start, out of these 3 parameters I am interested in the 2nd and 3rd parameters, which are text and text size respectively, I read them with printn(peeks(*buffer,-1,#pbutf8)) but if I try to pass the text in a variable string string.s=peeks(*buffer,-1,#pbutf8)), it crashes, if instead I use a fixed string for example *fixedbuffer=utf8("example string") the program does not crash...

this not crash:

Code: Select all

ProcedureCDLL My_Function(*primo, *secondo, ProgramParam3);, IGNORARE IL PRIMO
  Protected *funzione, Speciale, *Tradotto,Stringa.s,*test
  *funzione = GetModuleHandle_("myprocess.exe") + $D111
PrintN("STRINGA_READMEMORY: "+PeekS(*SECONDO,-1,#PB_UTF8))<--------------------------
CallCFunctionFast(*funzione + 5, *primo, *ProgramParam2, ProgramParam3); Terzo
 ProcedureReturn
EndProcedure
this not crash:

Code: Select all

ProcedureCDLL My_Function(*primo, *ProgramParam2, ProgramParam3);, IGNORARE IL PRIMO
  Protected *funzione, Speciale, *Tradotto,Stringa.s
  *funzione = GetModuleHandle_("myprocess.exe") + $D111
PrintN("STRINGA_READMEMORY: "+PeekS(*SECONDO,-1,#PB_UTF8))
*test=utf8("example string")<---------------------------
CallCFunctionFast(*funzione + 5, *primo, *Secondo, ProgramParam3); + StringByteLength(Testo2)
 ProcedureReturn
EndProcedure
this crash:

Code: Select all

ProcedureCDLL My_Function(*primo, *secondo, ProgramParam3);, IGNORARE IL PRIMO
  Protected *funzione, Speciale, *Tradotto,Stringa.s
  *funzione = GetModuleHandle_("myprocess.exe") + $D111
STRINGA=PeekS(*ProgramParam2,-1,#PB_UTF8) <-----------------------
CallCFunctionFast(*funzione + 5, *primo, *Secondo, ProgramParam3); + StringByteLength(Testo2)
 ProcedureReturn
EndProcedure
this also crash:

Code: Select all

ProcedureCDLL My_Function(*primo, *secondo, ProgramParam3);, IGNORARE IL PRIMO
  Protected *funzione, Speciale, *Tradotto,Stringa.s
  *funzione = GetModuleHandle_("myprocess.exe") + $D111
STRINGA=""<-----------------------
CallCFunctionFast(*funzione + 5, *primo, *Secondo, ProgramParam3); + StringByteLength(Testo2)
 ProcedureReturn
EndProcedure
also crash with MemorySize(*secondo), and crash sometime also with only peeks, how to check if buffer is accessible and readable to avoid problem?
Image
Post Reply