Skip to content

EM_STREAMOUT

Viewing 7 posts - 16 through 22 (of 22 total)
  • Author
    Posts
  • #188474

    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.

    #188473
    Ryuu99
    Member

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

    #188472
    Ryuu99
    Member

    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.


    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.

    #188471

    i’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

    #188470
    Ryuu99
    Member

    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.

    #188469
    Ryuu99
    Member

    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.

    #188468

    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 🙂

Viewing 7 posts - 16 through 22 (of 22 total)
  • You must be logged in to reply to this topic.