EM_STREAMOUT

You can talk about VB programming here

Postby BattleStar-Galactica » Fri Sep 15, 2006 5:53 pm


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.
User avatar
BattleStar-Galactica
imFiles Master
imFiles Master
 
Posts: 565
Joined: Tue Sep 20, 2005 12:19 am
Location: safest place to hide

Postby Ryuu99 » Fri Sep 15, 2006 9:46 pm

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.
Ryuu99
imFiles Newbie
imFiles Newbie
 
Posts: 9
Joined: Sun Sep 10, 2006 7:05 pm

Postby Ryuu99 » Sat Sep 16, 2006 7:19 pm

The 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.

Code: Select all
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 += '\0';   //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:
Code: Select all
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
Code: Select all
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.
Ryuu99
imFiles Newbie
imFiles Newbie
 
Posts: 9
Joined: Sun Sep 10, 2006 7:05 pm

Postby BattleStar-Galactica » Sun Sep 17, 2006 2:35 am

i'm using a hook like this
Code: Select all
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
User avatar
BattleStar-Galactica
imFiles Master
imFiles Master
 
Posts: 565
Joined: Tue Sep 20, 2005 12:19 am
Location: safest place to hide

Postby Ryuu99 » Wed Sep 20, 2006 4:36 pm

As 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.
Ryuu99
imFiles Newbie
imFiles Newbie
 
Posts: 9
Joined: Sun Sep 10, 2006 7:05 pm

Postby Ryuu99 » Sat Sep 23, 2006 5:20 pm

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


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.
Ryuu99
imFiles Newbie
imFiles Newbie
 
Posts: 9
Joined: Sun Sep 10, 2006 7:05 pm

Postby BattleStar-Galactica » Sat Sep 23, 2006 9:16 pm

yep, I have documented on your method, and i know that call will execute the code under dll process attach. I have tested with success :)
User avatar
BattleStar-Galactica
imFiles Master
imFiles Master
 
Posts: 565
Joined: Tue Sep 20, 2005 12:19 am
Location: safest place to hide

Previous

Return to Visual Basic Programming

Who is online

Users browsing this forum: No registered users and 0 guests