- This topic has 21 replies, 5 voices, and was last updated 18 years ago by Newbie.
-
AuthorPosts
-
September 15, 2006 at 10:53 pm #188474BattleStar-GalacticaMember
unless he proves me, it’s necessary to subclass a specific control for a specific thing. at the moment I dont think we need to install our winproc to make a programm for fun with pt.
September 16, 2006 at 2:46 am #188473Ryuu99Member@Departure wrote:
what do you mean anyone daring to subclass??
All the paltalk programs on here are made because of subclassing down to the richedit box, thats what every single pal app is based on (subclassing)
On the contrary, most programs I have seen here worked strictly through SendMessage/PostMessage commands. Subclassing requires being in the same addressing space as the application, and I haven’t seen much code injection going on here.
It’s true that for a lot of applications dealing with Paltalk, dll injection isn’t necessary, or even worth the performance loss. It isn’t so much subclassing which causing the performance drop, but using hooks can slow it down a bit. I decided to go the injection/subclassing route because of two things. a) I wanted to modify the toolbar in chat/IM windows to replace the standard font dialog with my own, and b) I wanted to implement the color fading utilizing the rich edit control already provided by Paltalk, and subclassing made it MUCH faster and cleaner to write.
September 17, 2006 at 12:19 am #188472Ryuu99MemberThe following code is in C++… Someone should be able to convert it though.. This is a snippet example of how to use EM_STREAMOUT.
The following function injects my dll into the target window’s thread.
BOOL Inject(HWND hTarget, LPTSTR dll)
{
DWORD procID;
GetWindowThreadProcessId(hTarget, &procID);
// Find the address of the LoadLibrary api
HMODULE hLocKernel32 = GetModuleHandle("Kernel32");
FARPROC hLocLoadLibrary = GetProcAddress(hLocKernel32, "LoadLibraryA");
//Adjust token privileges to open system processes
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, 0, &tkp, sizeof(tkp), NULL, NULL);
}
//Open the process with all access
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
//Allocate memory to hold the path to the dll File in the process's memory
dll += ''; //Add the null-terminator just in case
LPVOID hRemoteMem = VirtualAllocEx(hProc, NULL, strlen(dll)+1, MEM_COMMIT, PAGE_READWRITE);
//Write the path to the Dll File in the location just created
DWORD numBytesWritten;
WriteProcessMemory(hProc, hRemoteMem, dll, strlen(dll)+1, &numBytesWritten);
//Create a remote thread that starts begins at the LoadLibrary function and is passed are memory pointer
HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)hLocLoadLibrary, hRemoteMem, 0, NULL);
//Wait for the thread to finish
BOOL res = FALSE;
if (hRemoteThread)
res = (BOOL)WaitForSingleObject(hRemoteThread, MAXWAIT) != WAIT_TIMEOUT;
else
{
VirtualFreeEx(hProc, hRemoteMem, strlen(dll)+1, MEM_RELEASE);
MessageBox(NULL, "Failed to create remote thread!", "", MB_OK);
}
//Free the memory created on the other process
VirtualFreeEx(hProc, hRemoteMem, strlen(dll)+1, MEM_RELEASE);
//Release the handle to the other process
CloseHandle(hProc);
return res;
}
After the dll in injected.. You can use EM_STREAMOUT within the dll. You may also use other methods to inject the dll (hooks, etc..). The following is an example:
The Callback Function:
DWORD MyCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
// cb is the number of bytes you need to read
// pcb needs to be set to the number of bytes you actually read
// pbBuff is a pointer to the buffer that contains the RTF data
// dwCookie is the same value that you passed with the SendMessage call
// If you read all the data, use *pcb = cb
// If you read, say 10 bytes, use *pcb = 10
return 0; // Return 0 to indicate success, non-zero for error
}
The Call
EDITSTREAM es;
es.dwCookie = NULL; // This is an unsigned long value that is sent to callback, basically just app-defined data
es.dwError = NULL; // This contains the last error that occured, 0 means success
es.pfnCallback = (EDITSTREAMCALLBACK)MyCallback;
SendMessage(hTargetRichEditBox, EM_STREAMOUT, SF_RTF, (LPARAM)&es);
Note the following:
The control calls the callback function repeatedly, transferring a portion of the data with each call. The control continues to call the callback function until one of the following conditions occurs:
* The callback function returns a nonzero value.
* The callback function returns zero in the *pcb parameter.
* An error occurs that prevents the rich edit control from transferring data into or out of itself. Examples are out-of-memory situations, failure of a system function, or an invalid character in the read buffer.That means your callback function will be called at minimum TWICE. Be prepared for reading NO data and returning 0, lol.
September 17, 2006 at 7:35 am #188471BattleStar-GalacticaMemberi’m using a hook like this
HMODULE hDll = ::LoadLibrary("testhookptwin.dll");
FnPtrTInstallDLL FnPtr = (FnPtrTInstallDLL)::GetProcAddress(hDll,"InstallCBThook");
if(FnPtr)
(FnPtr)(dwID,rich20,parent);
::FreeLibrary(hDll);
my code work fine but I want to understand your method
BOOL Inject(HWND hTarget, LPTSTR dll)
hTarget is the the parent window or the child and your const MAXWAIT is how many miliseconds.
and how i can call my function in my dll like my code on top after de dll is injected
thanks in advance
September 20, 2006 at 9:36 pm #188470Ryuu99MemberAs of now, I am no longer using my method to inject the dll. I am now using a CBT hook (similar to your method). The difference the hooking method and my previously written method is that in my previous method, there was no contact ever made between the injector and the injectee(is that a word? haha). Basically I allocated memory in the target process and wrote the LoadLibrary parameter in the allocated memory. Then I get the proc address of LoadLibrary in MY OWN thread (windows ALWAYS loads the kernel library in every process at the same address). I then tell the target process to create a new thread, where the new thread’s entry point is LoadLibrary, and LoadLibrary’s parameter (the dll to load) is a pointer to the memory I had written to the process earlier. I then wait a maximum of X seconds for the LoadLibrary call to finish and the dll to attach.
There is NO communication between the ‘server’ application and the injected dll with that method. The positive side of it is that it doesn’t require hooking either. I am using a CBT hook now so that I could see when Paltalk was activating new windows.
September 23, 2006 at 10:20 pm #188469Ryuu99Membermy code work fine but I want to understand your method
BOOL Inject(HWND hTarget, LPTSTR dll)
hTarget is the the parent window or the child and your const MAXWAIT is how many miliseconds.
and how i can call my function in my dll like my code on top after de dll is injected
thanks in advance
I just reread what I typed earlier and it probably seemed rather confusing… so allow me to just answer your questions in order.
hTarget is the target window handle that you want to inject your code into (it’s a thread specific hook). My const MAXWAIT is 10 seconds (10000 milliseconds, but it never takes that long. That’s just an indication that the call failed miserably. With that injection method, you cannot make calls to export functions in the dll. You have no form of communication whats-so-ever.
September 24, 2006 at 2:16 am #188468BattleStar-GalacticaMemberyep, I have documented on your method, and i know that call will execute the code under dll process attach. I have tested with success 🙂
-
AuthorPosts
Related
- You must be logged in to reply to this topic.