dustbyter Posted December 13, 2015 Posted December 13, 2015 Any win32 coders that can help answer a question regarding the clipboard API? Quote
AlfAlfa Posted December 13, 2015 Posted December 13, 2015 Yes what is the question? Can't answer until after 6:30am as this is my last post until then so you should've just asked it lol... Windows APIs are my specialty before I started with all the linux goodness P.S. did you try the --make-it-work option? lol Quote
dustbyter Posted December 13, 2015 Author Posted December 13, 2015 Hi AlfAlfa, I'm looking to implement the API for reading the clipboard. Seems it keeps failing. I can't figure out why. When stepping through the code with the debugger, it works. When running the executable, it fails. wchar_t *getClipboardText(void) { if( OpenClipboard(NULL) ) { // if we don't find any text of UNICODE format, then we can't copy it if ( IsClipboardFormatAvailable(CF_TEXT) || IsClipboardFormatAvailable(CF_UNICODETEXT) ) { HANDLE hToken; wchar_t *wGlobal; hToken = GetClipboardData(CF_UNICODETEXT); if ( !hToken ) return L"Error-no hToken\0"; wGlobal = (wchar_t*)GlobalLock(hToken); GlobalUnlock(hToken); CloseClipboard(); return wGlobal; } else { return L"CF_UNICODETEXT format text not present, or no text on clipboard"; } } return L"Error-Cannot Open Clipboard\0"; } After adding the IsClipboardFormatAvailable() API call, it fails here... and returns return L"CF_UNICODETEXT format text not present, or no text on clipboard"; Prior to adding this API call, it would fail on the GetClipboardData call. I copy ANSI and UTF8 code, so i know what is on the clipboard is valid to be copied... but it doesn't work unless im debugging Any ideas? I'm just starting to play with win32 API Quote
AlfAlfa Posted December 13, 2015 Posted December 13, 2015 (edited) Okay dustbyter I threw your code into visual studio with a blank project and added an int main()... The clipboard grabbing code itself seems right, but if you only want unicode to be able to be copied just have it like, you don't need the 'or CF_TEXT' part: // if we don't find any text of UNICODE format, then we can't copy it if(IsClipboardFormatAvailable(CF_UNICODETEXT)) { Now I was unable to reproduce your problem though, either with debugging or running it straight up and as a release build... But I think it's probably because there isn't much going on in my test app, and in yours you probably use it many times and have much more going on in memory... However I suspect the problem is you are referencing a memory location that you don't own and trying to keep a pointer to it like you'll always be able to access it freely. Try making your own copy of the unicode text after the GlobalLock call, but before unlocking... Test this bare bones example which I used your code and it seemed to work for me, then I made my change to it using a std::unique_ptr to hold onto a copy of the retrieved clipboard contents, you could manually worry about having to free a raw wchar_t* but that's too old school I'm on the latest (C++11, C++ 14) C++ features now :D #include <Windows.h> #include <stdio.h> #include <memory> std::unique_ptr<wchar_t> getClipboardText(); int main(int argcount, char* args[]) { if(argcount > 1 && (strcmp(args[1],"-c") == 0 || strcmp(args[1],"--show-clipboard") == 0)) { std::unique_ptr<wchar_t> clipboardContents = getClipboardText(); printf("Clipboard Contents:\r\n%S", clipboardContents.get()); } return 0; } std::unique_ptr<wchar_t> getClipboardText() { if(OpenClipboard(0)) { // if we don't find any text of UNICODE format, then we can't copy it if(IsClipboardFormatAvailable(CF_UNICODETEXT)) { HANDLE hToken; wchar_t *wGlobal; hToken = GetClipboardData(CF_UNICODETEXT); if (!hToken) { OutputDebugStringW(L"Error-no hToken"); return 0; } wGlobal = (wchar_t*)GlobalLock(hToken); //Make your own copy of the clipboard contents, since you don't own the memory pointed to by wGlobal you can only access it temporarily when locked int contentsLength = wcslen(wGlobal) + 1; //(null terminator) std::unique_ptr<wchar_t> clipboardContents(new wchar_t[contentsLength]); memcpy(clipboardContents.get(),wGlobal,contentsLength*sizeof(wchar_t)); GlobalUnlock(hToken); CloseClipboard(); return std::move(clipboardContents); } else { OutputDebugStringW(L"CF_UNICODETEXT format text not present, or no text on clipboard"); } } OutputDebugStringW(L"Error-Cannot Open Clipboard"); return 0; } See if you can reproduce your problem in a test application, even though I haven't been able to... By the way what environment are you using, it could be something particular with that, or just something particular with your code... I hope you get it working, I'll help you further if you were able to have a small full example that reproduces your problem! :) Edited December 21, 2015 by AlfAlfa Quote
cooper Posted December 14, 2015 Posted December 14, 2015 std::unique_ptr<wchar_t> clipboardContents(new wchar_t[contentsLength]); Woah. That's how you declare a class-type variable and invoke its constructor in C++ these days? I am getting old... Quote
AlfAlfa Posted December 14, 2015 Posted December 14, 2015 (edited) std::unique_ptr<wchar_t> clipboardContents(new wchar_t[contentsLength]); Woah. That's how you declare a class-type variable and invoke its constructor in C++ these days? I am getting old... Well actually I meant to make it "std::unique_ptr<wchar_t[]>" that way you can index an individual character if you wanted: clipboardContents... Yes you don't have to though, but I like using them that way you just keep it in scope for as long as you want it to live and it frees itself when it goes out of scope or you re-assign it or reset it! C++ does like the smarter way to garbage collect, it's not garbage collection though, it's still manual memory management but in a smart way! EDIT: To be more clear the line constructs both a std::unique_ptr object and it's constructor gets passed the construction of your actual object or array of objects you want the unique pointer to point to... shared pointer used if you need multiple references to the same object lol remember: char *rawCharacters = (char*)malloc(1024); memset(rawCharacters, 0, 1024); //... free(rawCharacters); :) Hi AlfAlfa, I'm looking to implement the API for reading the clipboard. Seems it keeps failing. I can't figure out why. When stepping through the code with the debugger, it works. When running the executable, it fails. wchar_t *getClipboardText(void) { if( OpenClipboard(NULL) ) { // if we don't find any text of UNICODE format, then we can't copy it if ( IsClipboardFormatAvailable(CF_TEXT) || IsClipboardFormatAvailable(CF_UNICODETEXT) ) { HANDLE hToken; wchar_t *wGlobal; hToken = GetClipboardData(CF_UNICODETEXT); if ( !hToken ) return L"Error-no hToken\0"; wGlobal = (wchar_t*)GlobalLock(hToken); GlobalUnlock(hToken); CloseClipboard(); return wGlobal; } else { return L"CF_UNICODETEXT format text not present, or no text on clipboard"; } } return L"Error-Cannot Open Clipboard\0"; } After adding the IsClipboardFormatAvailable() API call, it fails here... and returns return L"CF_UNICODETEXT format text not present, or no text on clipboard"; Prior to adding this API call, it would fail on the GetClipboardData call. I copy ANSI and UTF8 code, so i know what is on the clipboard is valid to be copied... but it doesn't work unless im debugging Any ideas? I'm just starting to play with win32 API EDIT: dustbyter another update... You went to a console application so I went to a GUI application for a couple reasons: To test whether adding a window handle of a window we own to the OpenClipboard call would help, and because I came up with a new idea... I got the idea from usb devices that also function as keyboards often used for exploitation. If we're having trouble with the APIs to grab the clipboard, maybe lets just simulate a CTRL+V keypress and capture whatever gets pasted in a window we create, then grab the text from there! It's worth a try, and it is an alternative method :) I've divided this one up into 3 tests ran on 3 separate threads, but it waits for each test to complete before running the next one. 1st: send CTRL+V via SendInput after waiting for the application to open and have focus on the edit control, then use GetWindowTextW to grab the text from it as unicode 2nd: IsClipboardFormatAvailable called on all three text formats CF_UNICODETEXT, CF_TEXT, and CF_OEMTEXT (because of synthesized clipboard formats, this shouldn't be necessary since as long as any text format is available it will convert to your desired text format which is unicode in this case) 3rd: EnumClipboardFormats to show you ALL of the available formats and display the unicode text format contents if they are available Finally in your last post you said it failed with the error described in your first post, but that was only using IsClipboardFormatAvailable, what is your results for the enumeration of formats test (test 3) ? If it's failing saying unicode text isn't available that shouldn't be the case as long as any text is available since I learned that it will automatically convert between the text formats to the one you want when you call GetClipboardData(format); And if it's failing there, that means it didn't fail on the OpenClipboard call right? So we do, have access to the clipboard, it's just what is actually on it... Maybe there really isn't text on the clipboard and it's another format... That's why I wanted to see the results of the enumeration rather than just checking one particular format individually! Let me know if the control + v paste and grab text method works... It closes the window after the third test finishes so you won't leave it running if your testing this on a remote machine :D #include <Windows.h> #include <stdio.h> #include <memory> #include <thread> #define ID_EDITCHILD 200 LRESULT WINAPI WindowProcedure(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam); int SetDebugPrivileges(); void PrintLastError (const char *msg); class AppData { private: static std::unique_ptr<AppData> data; public: HINSTANCE hInst; HWND hWnd, editWnd; wchar_t clipboardText[2048]; char debugText[1024]; AppData() { hInst = 0; hWnd = 0; editWnd = 0; memset(clipboardText, 0, 4096); } static AppData* get() { if(!data.get()) data = std::unique_ptr<AppData>(new AppData()); return data.get(); } }; std::unique_ptr<AppData> AppData::data; AppData *d = AppData::get(); class Clipboarder { public: static std::unique_ptr<wchar_t[]> contents; static std::thread spawnTest1() { return std::thread( [=] { NEWControlVGetText_test1(); } ); } static std::thread spawnTest2() { return std::thread( [=] { isTextOfAnyKindAvailable_test2(); } ); } static std::thread spawnTest3() { return std::thread( [=] { enumerateAllFormatsWhatFormatsAreAvailable_test3(); } ); } static void NEWControlVGetText_test1() { INPUT ip[2]; OutputDebugStringW(L"\r\nTest1... Hit Control+V, wait a couple seconds, then grab the text from the edit control window :)"); memset(&ip[0], 0, sizeof(INPUT)*2); // Pause for 3 seconds. Sleep(3000); SetForegroundWindow(AppData::get()->hWnd); SetForegroundWindow(AppData::get()->editWnd); SetFocus(AppData::get()->editWnd); // Set up a generic keyboard event. ip[0].type = ip[1].type = INPUT_KEYBOARD; // Press the "CTRL" key ip[0].ki.wVk = VK_LCONTROL; // virtual-key code for the left control key // Press the "V" key ip[1].ki.wVk = 'V'; // virtual-key code for the "v" key SendInput(2, &ip[0], sizeof(INPUT)); // Release both keys ip[0].ki.dwFlags = ip[1].ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release SendInput(2, &ip[0], sizeof(INPUT)); // Pause for another 2 seconds. Sleep(2000); //Then grab pasted text (if it pasted successfully to our edit control within our window) GetWindowTextW(AppData::get()->editWnd, AppData::get()->clipboardText, 2048); OutputDebugStringW(L"Control+V Paste And GetWindowText Clipboard Contents:"); contents = makeWideString(AppData::get()->clipboardText); OutputDebugStringW(contents.get()); std::thread test2 = spawnTest2(); test2.join(); std::thread test3 = spawnTest3(); test3.join(); SendMessageW(AppData::get()->hWnd, WM_CLOSE, 0, 0); //close the application after our 3 tests complete... } static void isTextOfAnyKindAvailable_test2() { HANDLE hToken; wchar_t *wGlobal; OutputDebugStringW(L"\r\nTest2... Use IsClipboardFormatAvailable to check if text of any kind is available..."); if(IsClipboardFormatAvailable(CF_UNICODETEXT) || IsClipboardFormatAvailable(CF_TEXT) || IsClipboardFormatAvailable(CF_OEMTEXT)) { //If any one of the three is available, then all should be available as GetClipboardData will convert between the text types for you as long as one is available... OutputDebugStringW(L"CF_UNICODETEXT and CF_TEXT and CF_OEMTEXT should all be available..."); if(!OpenClipboard(AppData::get()->hWnd)) { PrintLastError("Error-Cannot Open Clipboard"); return; } hToken = GetClipboardData(CF_UNICODETEXT); if(!hToken) { PrintLastError("Error-no hToken"); return; } wGlobal = (wchar_t*)GlobalLock(hToken); contents = makeWideString(wGlobal); OutputDebugStringW(L"Clipboard Contents From Test2:\r\n"); OutputDebugStringW(contents.get()); GlobalUnlock(hToken); CloseClipboard(); } else { PrintLastError("Niether CF_UNICODETEXT nor CF_TEXT nor CF_OEMTEXT are present... (according to IsClipboardFormatAvailable())"); } } static void enumerateAllFormatsWhatFormatsAreAvailable_test3() { HANDLE hToken; wchar_t *wGlobal; OutputDebugStringW(L"\r\nTest3... Enumerate all available formats, show them, and grab unicode text successfully as long as any kind of text is available..."); AppData *d = AppData::get(); if(OpenClipboard(d->hWnd)) { OutputDebugStringW(L"Getting Available Clipboard Formats...\r\n"); int numFormats = CountClipboardFormats(); sprintf_s(d->debugText,"Number of available clipboard formats: %u\r\n",numFormats); OutputDebugStringA(d->debugText); UINT format = EnumClipboardFormats(0); UINT i = 0; while(format != 0) { if(format == CF_OEMTEXT) sprintf_s(d->debugText,"#%u available format: %u (CF_OEMTEXT)\r\n",++i,format); else if(format == CF_TEXT) sprintf_s(d->debugText,"#%u available format: %u (CF_TEXT)\r\n",++i,format); else if(format == CF_UNICODETEXT) sprintf_s(d->debugText,"#%u available format: %u (CF_UNICODETEXT)\r\n",++i,format); else if(format == CF_BITMAP) sprintf_s(d->debugText,"#%u available format: %u (CF_BITMAP)\r\n",++i,format); else if(format == CF_OWNERDISPLAY) sprintf_s(d->debugText,"#%u available format: %u (CF_OWNERDISPLAY)\r\n",++i,format); else if(format == CF_WAVE) sprintf_s(d->debugText,"#%u available format: %u (CF_WAVE)\r\n",++i,format); else sprintf_s(d->debugText,"#%u available format: %u\r\n",++i,format); OutputDebugStringA(d->debugText); //No need to check for the other two here, EnumClipboardFormats will have unicode as an available format if CF_TEXT or CF_OEMTEXT is available. if(format == CF_UNICODETEXT) { hToken = GetClipboardData(format); if(!hToken) { OutputDebugStringW(L"Error-no hToken"); continue; } wGlobal = (wchar_t*)GlobalLock(hToken); //output contents if unicode is an available format returned from EnumClipboardFormats! (it should be as long as any kind of text is available...) contents = makeWideString(wGlobal); OutputDebugStringW(L"Clipboard Contents From Test3:\r\n"); OutputDebugStringW(contents.get()); GlobalUnlock(hToken); } format = EnumClipboardFormats(format); } CloseClipboard(); } } static std::unique_ptr<wchar_t[]> makeWideString(wchar_t *fromWideString) { int stringLength = wcslen(fromWideString) + 1; //(null terminator) std::unique_ptr<wchar_t[]> madeWideString(new wchar_t[stringLength]); memcpy(madeWideString.get(),fromWideString,stringLength*sizeof(wchar_t)); return std::move(madeWideString); } }; std::unique_ptr<wchar_t[]> Clipboarder::contents; int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) { MSG messages; WNDCLASSEXA wcx; LPCSTR szClassName = "ClipboarderClass", szWindowName = "Clipboarder-ng"; d->hInst = hInstance; wcx.hInstance = d->hInst; wcx.lpszClassName = szClassName; wcx.lpfnWndProc = WindowProcedure; wcx.style = CS_HREDRAW|CS_VREDRAW; wcx.cbSize = sizeof(WNDCLASSEXW); wcx.hIcon = LoadIcon(0, IDI_APPLICATION); wcx.hIconSm = LoadIcon(0, IDI_APPLICATION); wcx.hCursor = LoadCursor(0, IDC_ARROW); wcx.lpszMenuName = 0; wcx.cbClsExtra = 0; wcx.cbWndExtra = 0; wcx.hbrBackground = (HBRUSH)COLOR_BTNFACE; if(!RegisterClassExA(&wcx)) return 0; SetDebugPrivileges(); //might help on XP systems... d->hWnd = CreateWindowA(szClassName,szWindowName,WS_SYSMENU | WS_THICKFRAME,CW_USEDEFAULT,CW_USEDEFAULT,600,420,HWND_DESKTOP,0,d->hInst,0); d->editWnd = CreateWindowExW(0,L"EDIT", 0, // no window title WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, // set size in WM_SIZE message d->hWnd, // parent window (HMENU) ID_EDITCHILD, // edit control ID (HINSTANCE) GetWindowLong(d->hWnd, GWL_HINSTANCE), 0); // pointer not needed UpdateWindow(d->hWnd); ShowWindow(d->hWnd, nShowCmd); std::thread test1 = Clipboarder::spawnTest1(); //test1 also spawns tests 2 and 3... while(GetMessage(&messages,0,0,0)) { TranslateMessage(&messages); DispatchMessage(&messages); } test1.join(); //join up with all three tests before exiting... return messages.wParam; } LRESULT WINAPI WindowProcedure(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_PAINT: ValidateRect(hwnd,FALSE); return TRUE; case WM_SIZE: // Make the edit control the size of the window's client area. MoveWindow(d->editWnd, 0, 0, // starting x- and y-coordinates LOWORD(lParam), // width of client area HIWORD(lParam), // height of client area TRUE); // repaint window return 0; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,message,wParam,lParam); } return 0; } int SetDebugPrivileges() { TOKEN_PRIVILEGES priv = {0}; HANDLE hToken = NULL; if( OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) ) { priv.PrivilegeCount = 1; priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if( LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid ) ) { if(AdjustTokenPrivileges( hToken, FALSE, &priv, 0, NULL, NULL ) == 0) { sprintf_s(AppData::get()->debugText,"AdjustTokenPrivilege Error! [%u]\n",GetLastError()); OutputDebugStringA(AppData::get()->debugText); } else OutputDebugStringW(L"Debug Privileges Set Successfully!"); } CloseHandle( hToken ); } return GetLastError(); } void PrintLastError (const char *msg) { DWORD errCode = GetLastError(); char *err; if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language (LPTSTR) &err, 0, NULL)) return; static char buffer[1024]; //sprintf(buffer,"%s: %X %s\n", msg, errCode, err); sprintf_s(buffer,"%s: %X %s\n", msg, errCode, err); OutputDebugStringA(buffer); LocalFree(err); } My results of running this application with all three tests: (after copying text from within Microsoft Visual C++ IDE) Edited December 18, 2015 by AlfAlfa Quote
dustbyter Posted December 14, 2015 Author Posted December 14, 2015 Thanks for this I'll check it out and try to run the code through a little application with just a main. Current set up is to have it pull the clipboard remotely. Was trying to extend a project that was provided as training material from a BlackHat course I took. Quote
dustbyter Posted December 14, 2015 Author Posted December 14, 2015 I converted the project to a console application and it worked flawlessly. Hmm - making me wonder if the issue is in the agent's project. The idea is that there are agents that get deployed on various windows boxes on a network and you have a way to speak to them. Tried it on WinXP, Win7, Win10 systems thus far and it fails on all them with the error as described in the first post. Just stumps me as not sure why the application won't get access to the clipboard. Quote
AlfAlfa Posted December 18, 2015 Posted December 18, 2015 (edited) I converted the project to a console application and it worked flawlessly. Hmm - making me wonder if the issue is in the agent's project. The idea is that there are agents that get deployed on various windows boxes on a network and you have a way to speak to them. Tried it on WinXP, Win7, Win10 systems thus far and it fails on all them with the error as described in the first post. Just stumps me as not sure why the application won't get access to the clipboard. In an effort to not turn this thread into walls of code (lol) I have edited my third post with my third update... With a new method, hopefully the CTRL+V plus getwindowtext will work for us :D P.S. I added a "SetDebugPrivileges()" function since you mentioned XP... Since it might help for XP... I remember having to use that to get full administrator access within your application on XP (even though you are always running as administrator it was just an extra step on XP, on later systems it didn't seem to matter much though and instead you needed administrator access in cases where SetDebugPrivileges with SE_DEBUG_NAME privilege would work on XP) I mean this is just the clipboard here, it shouldn't be this tricky just to grab whats on it! :) Edited December 18, 2015 by AlfAlfa Quote
cooper Posted December 19, 2015 Posted December 19, 2015 If you fear showing swathes of code, use the spoiler tag to hide it from those that would be unable to deal with that level of nerd porn. Quote
dustbyter Posted December 20, 2015 Author Posted December 20, 2015 Sorry, haven't had time to play with this given the holidays. I'll play with it hopefully next week and provide some updates. Quote
AlfAlfa Posted December 21, 2015 Posted December 21, 2015 If you fear showing swathes of code, use the spoiler tag to hide it from those that would be unable to deal with that level of nerd porn. Thanks for the tip Cooper! I've applied it to the previous post, and the latest best post is visible without expanding anything. :) Sorry, haven't had time to play with this given the holidays. I'll play with it hopefully next week and provide some updates. That's cool, whenever you do though, maybe the text isn't on the clipboard as a text format. Perhaps it's encoded or encrypted and stored on the clipboard in a data format or custom format! Did you think of that? I haven't however found a way to determine the clipboard size of any available clipboard format though. I think you just have to know how to read whatever format you need... So maybe the next thing would be to actually get the data from all available formats and read the first 10 bytes or something like that and see if anything looks familiar or if it looks encrypted :) Quote
dustbyter Posted December 21, 2015 Author Posted December 21, 2015 I know the text is in ASCII or UTF8 format as i would copy a string like "The monkey" from notepad. I tried the same code, but having it be injected into memory and it runs then. So something is going on with the process that is first loaded and not the code itself. Quote
dustbyter Posted December 29, 2015 Author Posted December 29, 2015 (edited) Worked on this a bit today and didn't have any luck. Starting to suspect maybe some type of permission issue?? although its not a very critical task... just reading the clipboard. From a goal perspective, I am able to load a dll into memory of target machine and read clipboard that way, but would have been nice to add it to the stage 1 executable. EDIT: When the process runs as Local System (service) then does not work. But if it runs as a user who is an admin on the system, then it runs just fine... Edited December 29, 2015 by dustbyter Quote
AlfAlfa Posted December 30, 2015 Posted December 30, 2015 Awesome! You got it! So it turns out a system level service process can't access the clipboard with those APIs... Injecting a dll containing the code into a regular user process does work though. Good to know. Quote
dustbyter Posted December 30, 2015 Author Posted December 30, 2015 Exactly! I'll see if there would be a way for the system level process to get the clipboard as well. I don't see why that would be prevented... Quote
AlfAlfa Posted December 30, 2015 Posted December 30, 2015 Well I'm thinking it's not that it's intentionally prevented or blocked, but just the fact that it is a lower level process which doesn't have access to win32 gui stuff, like the clipboard. You have to provide a way around it like you have, to reach over into win32 gui land. It's kind of like how with trying to execute a gui application through php's "exec" function can't and wont work! When I've had to do that you have to work around it (in that case I had a gui application running with a pipe or socket open, then through the php code send it what gui application to run and then have it execute it instead of php directly executing it) I know a little off track here but it is a similar issue. Perhaps if you build a kernel driver or some deeper system calls could get you through to the clipboard without the extra dll injecting step! Like even debugging the clipboard apis and see what lower level apis they use could also get you through. Quote
dustbyter Posted December 30, 2015 Author Posted December 30, 2015 Did some research, and seems that its a user issue. Since my service is running as a different account, it cannot reach into the clipboard of the active user, as they have a "different" clipboard. I would need to somehow figure out a way to sign in as that other user from my service. Probably not worth the effort, since the DLL injection works just fine. Quote
AlfAlfa Posted December 31, 2015 Posted December 31, 2015 That makes sense as well...So it is trying to protect the user's clipboard, well unsuccessfully though as that's a simple workaround! lol Take that m1crosh4ft!! :D haha Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.