How can I run LoadEnclaveData function in memory? - winapi

I read about memory enclaves, and I found it an interesting feature to hide some data, so, here I am.
I wasn't able to find anything on the API required, but the MSDN documentation has [no source code on usage], I know that I have to call the following:
IsEnclaveTypeSupported : to make sure I can continue.
CreateEnclave : to return the base address of the enclave created, although I struggled with this one too, but this question helped me.
LoadEnclaveData : to add the data to our created enclave.
InitializeEnclave : to activate the enclave.
based on Windows Internal book (part 1), to execute I have to run the EENTER assembly instruction, which also I didn't find information on, but I think CallEnclave with the base address of the enclave can do the job.
Anyways, I'm stuck at step 3, my LoadEnclaveData is returning error code 87, which is ERROR_INVALID_PARAMETER.
I'm only copying NOPs (0x90) to the address, just to see it through the debugger that is running.
Here is the code:
LPVOID lpAddress ;
ENCLAVE_CREATE_INFO_VBS VBS = { 0 };
VBS.Flags = 0;
HANDLE hProcess = GetCurrentProcess();
lpAddress = CreateEnclave(
hProcess,
NULL,
2097152,
NULL,
ENCLAVE_TYPE_VBS,
&VBS,
sizeof(ENCLAVE_CREATE_INFO_VBS),
NULL
);
printf("[-] GetLastError : %d \n", GetLastError());
printf("[+] %-20s : 0x%-016p\n", "lpAddress addr", (void*) lpAddress);
unsigned char buffer[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 , 0x90 , 0x90 };
LoadEnclaveData(
hProcess,
lpAddress,
&buffer,
sizeof(buffer),
PAGE_READWRITE,
NULL,
0,
0,
0
);
printf("[-] GetLastError : %d \n", GetLastError());
Based on MSDN's LoadEnclaveData documentation, they didn't specify what to do with lpPageInformation, so I think it is the problem, but they said The lpPageInformation parameter is not used. So I recheck a couple of parameters, and I found out that nSize must be a whole-number multiple of the page size. So I got confused, what to do now?
In case anyone is sure about executing a buffer in an enclave, please let me know.
And BTW, the thing in choosing the title is killing me, [I wasted more time on that than writing this].

Related

Shared memory changes aren't visible in different process

I have a problem. As far as I know, processes in Windows share dynamic-linked libraries among each other, allowing only one instance of every library to exist at once in the memory. Knowing that, I wrote a small program in C, which can change some data in this shared section. In my example, I chose to change the beginning of MessageBoxW function. This is the code:
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#define SIZE 12 // size of JMP byte array defined below
int WINAPI CustomMessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT);
void BeginRedirect(LPVOID);
// JMP bytes translated to assembly (x64):
// mov rax, 0x1234567890ABCDEF - this value will be changed to newFunction address, in BeginRedirect procedure
// jmp rax - jump to newFunction
BYTE JMP[SIZE] = { 0x48, 0xB8, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xFF, 0xE0 };
DWORD oldProtect, myProtect = PAGE_EXECUTE_READWRITE;
int main()
{
printf("MessageBoxW address: %p\n", MessageBoxW);
printf("redirect? ");
char res[4];
scanf_s("%4s", res, _countof(res));
if (strcmp(res, "yes") == 0) // redirect
{
printf("redirecting...\n");
BeginRedirect(MessageBoxW, CustomMessageBoxW);
}
while (1)
{
MessageBoxW(NULL, L"This is original MessageBoxW", L"Caption", MB_OKCANCEL);
printf("MessageBoxW address: %p\nBytes:\n", MessageBoxW);
for (int i = 0; i < 20; i++)
{
printf("0x%hhX ", *((char*)MessageBoxW + i));
}
puts("\n");
SleepEx(1000, FALSE);
}
}
void BeginRedirect(LPVOID oldFunction, LPVOID newFunction)
{
BYTE tempJMP[SIZE];
memcpy(tempJMP, JMP, SIZE);
BOOL result = VirtualProtect(oldFunction, SIZE, PAGE_EXECUTE_READWRITE, &oldProtect);
printf("\tVirtualProtect result: %u\n", result);
memcpy(tempJMP + 2, &newFunction, 8); // change the basic 0x1234... address to the actual function address
memcpy(oldFunction, tempJMP, SIZE);
result = VirtualProtect(oldFunction, SIZE, oldProtect, &myProtect);
printf("\tVirtualProtect result: %u\n", result);
}
int WINAPI CustomMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uiType)
{
printf("MyMessageBoxW: Custom message\n");
}
The program allows to choose if I want to redirect the function in the current instance of the program. Here comes the interesting part.
I run a first instance. When asked if to redirect, I type "yes", so the program does. It changes the beginning code of MessageBoxW, so that it points to my CustomMessageBoxW. Then, in the while loop, the program executes MessageBoxW every second and outputs some debugging information (first 20 bytes of the function). In this instance, the redirection works properly and instead of popup, the program outputs "MyMessageBoxW: Custom message" every second (as expected in CustomMessageBoxW)
Then, I run the second instance of the program (the first instance still executes!). Now, I decide not to redirect the function (type anything apart from "yes"). From the information printed by both instances about their MessageBoxW addresses, I can see that they're clearly identical. At that point, I thought that if the addresses are the same (both instances share one instance of user32.dll which contains MessageBoxW), then the second instance which didn't modify the MessageBoxW function itself will still attempt to execute the CustomMessageBoxW, which will probably result in memory access violation. But no. It turns out that the second instance works just fine and pops up a standard Windows message box, while the first instance (which still runs) still executes the redirected function (remember that in both program instances, the addresses of MessageBoxW are the same). Apart from that, the bytes outputed by
printf("MessageBoxW address: %p\nBytes:\n", MessageBoxW);
for (int i = 0; i < 20; i++)
{
printf("0x%hhX ", *((char*)MessageBoxW + i));
}
are completely different in both instances, while the function address is still the same.
I even decided to debug both instances at the same time using WinDbg, and it also showed that both instances stored different values under the same address. I'd really appreciate it if someone figured out what is actually going round here. Thanks!

Send data to a PS3 DualShock3 controller from a Mac (IOHIDDeviceSetReport)

I've been playing around with the HID part of IOKit lately on my Mac with a PS3 controller. I've managed to look though the sample code and connect to my controller, receive a stream of data and parse it (Everything, including the accelerometer and gyro).
However, today I decided I wanted to start setting the LEDs on the back of the device and triggering the rumble motors, but I just can't get it to work!
Looking though the sample code Apple provides for IOHID there isn't much I can see on setting things on the HID device, only receiving data. From looking on the web (for petty much half a day) I've got what I think is a working send method which uses IOHIDDeviceSetReport(). However, I can't work out what data I should be sending.
I've found several sites that list data examples:
http://www.circuitsathome.com/mcu/ps3-and-wiimote-game-controllers-on-the-arduino-host-shield-part-2
https://github.com/ribbotson/USB-Host/blob/master/ps3/PS3USB/ps3_usb.h
http://wiibrew.org/wiki/Sixaxis
(I know not all these examples are for between Mac an a PS3 controller)
A lot of people seem to be talking about this and even doing it (I refuse to believe no one has got this working) but I can't seem to find anything about actually how to do it that works!
I feel like I am missing a simple step here, so if anyone has any ideas, help or a solution please let me know.
Thanks.
Example Code of how I'm trying to send a report (is is returning success):
CFIndex len = 64;
uint8_t report[64] = {0x0};
IOReturn tIOReturn = IOHIDDeviceSetReport(deviceRef,
kIOHIDReportTypeOutput,
reportID,
report,
len);
This is just sending a lot of nothing (literally) but it's just an example of what I'm using just incase it's not correct.
Extra: I've also just noticed that Apples defenition of IOHIDDeviceSetReport differes from there example given.
https://developer.apple.com/library/mac/documentation/DeviceDrivers/Conceptual/HID/new_api_10_5/tn2187.html#//apple_ref/doc/uid/TP40000970-CH214-SW81
There it says report should be "address of report buffer". But...
https://developer.apple.com/library/mac/documentation/IOKit/Reference/IOHIDDevice_iokit_header_reference/Reference/reference.html#//apple_ref/doc/uid/TP40012408-CHIOHIDDevicehFunctions-DontLinkElementID_23
There it say *report (being a pointer) is "The report bytes to be sent to the device.".
there's an example at: http://www.circuitsathome.com/mcu/ps3-and-wiimote-game-controllers-on-the-arduino-host-shield-part-2
with the code describing the LED and Rumble control at:
https://github.com/ribbotson/USB-Host/blob/master/ps3/PS3USB/ps3_usb.cpp#L187
It seems that the bytes that you sent as report need to have a certain format:
prog_char output_01_report[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0xff, 0x27, 0x10, 0x00, 0x32, 0xff,
0x27, 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00,
0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
In the LEDRumble function, these bytes are copied into buf and then buf[9] is overridden to set the LED state and the bytes from buf[1] through buf[4] are used to configure the Rumble. The the bytes are all sent to the controller.
There are some constants defined here: https://github.com/ribbotson/USB-Host/blob/master/ps3/PS3USB/ps3_usb.h#L100
#define psLED1 0x01
#define psLED2 0x02
#define psLED3 0x04
#define psLED4 0x08
#define psRumbleHigh 0x10
#define psRumbleLow 0x20
These constants are passed to the LEDRumble function as parameters.
Their example seems fine, as far as I've read it. Under these circumstances, either an uint8_t[64] variable or an uint8_t* variable will be both interpreted as a pointer to uint8_t when passed to IOHIDDeviceSetReport.
I'm on a restricted network right now, so I won't be able to help any further. But I'll try to read a little bit more about this later at home, as I also have a related project in mind. If I find out anything that can help us on this, I'll get back here to talk about it.

Referencing GUIDs

I'm trying to capture an event and reference a GUID to see which event it is. The code is below:
DWORD WINAPI AvisionEventProc(LPVOID lpParam){
//HANDLE hEvent = * (HANDLE *) lpParam; // This thread's read event
STINOTIFY pStiNotify;
if (debug){
wprintf(L"Avision Event\n");
}
while(true){
WaitForSingleObject(hAvisionEvent, INFINITE);
wprintf(L"Event");
pStiDevice->GetLastNotificationData(&pStiNotify);
if (pStiNotify.guidNotificationCode == GUID_STIUserDefined1){
wprintf(L"User defined 1");
}else if (pStiNotify.guidNotificationCode == GUID_STIUserDefined2){
wprintf(L"User defined 2");
}else if (pStiNotify.guidNotificationCode == GUID_STIUserDefined3){
wprintf(L"User defined 3");
}
ResetEvent(hAvisionEvent);
}
return 1;
}
This compiles just fine but I get the errors below when linking:
1>sti.obj : error LNK2001: unresolved external symbol _GUID_STIUserDefined3
1>sti.obj : error LNK2001: unresolved external symbol _GUID_STIUserDefined2
1>sti.obj : error LNK2001: unresolved external symbol _GUID_STIUserDefined1
The strange thing is that sti.h is linked in as I am pulling other constants from it. I did notice by the GUID decleration the following:
#if defined( _WIN32 ) && !defined( _NO_COM)
/*
* Class IID's
*/
// B323F8E0-2E68-11D0-90EA-00AA0060F86C
DEFINE_GUID(CLSID_Sti, 0xB323F8E0L, 0x2E68, 0x11D0, 0x90, 0xEA, 0x00, 0xAA, 0x00, 0x60, 0xF8, 0x6C);
/*
* Interface IID's
*/
// {641BD880-2DC8-11D0-90EA-00AA0060F86C}
DEFINE_GUID(IID_IStillImageW, 0x641BD880L, 0x2DC8, 0x11D0, 0x90, 0xEA, 0x00, 0xAA, 0x00, 0x60, 0xF8, 0x6C);
<snip>
/*
* Standard event GUIDs
*/
// {740D9EE6-70F1-11d1-AD10-00A02438AD48}
DEFINE_GUID(GUID_DeviceArrivedLaunch, 0x740d9ee6, 0x70f1, 0x11d1, 0xad, 0x10, 0x0, 0xa0, 0x24, 0x38, 0xad, 0x48);
<snip>
#endif
Does the "if defined" line stop the GUIDs being referenced (I am writing a win32 console app) or is there something more fundamental I have wrong here to do with a lack of understanding on GUIDs?
Thanks, in advance for your help.
Cheers,
Neil
#include <initguid.h>should be added. That will help.
The DEFINE_GUID macro either defines a named GUID as a static, or just does a forward declaration to actually be done somewhere else, depending on if #include <initguid.h> has been previously declared. Your code perhaps only have the latter, and the symbols don't have actual initialization within the project.
See:
How to avoid error "LNK2001 unresolved external" by using DEFINE_GUID
INITGUID: An Explanation
How does the DEFINE_GUID macro work? - at the bottom of the page

SIGSEGV handler and mprotect and looping effect when injecting instructions at runtime. Handler can't get info->si_addr

I have looked at the various topics relating to this, but couldn't find this specific issue I am having.
Things I looked at:
Injecting code into executable at runtime
C SIGSEGV Handler & Mprotect
Can I write-protect every page in the address space of a Linux process?
How to write a signal handler to catch SIGSEGV?
I am able to handle SIGSEGV gracefully when the protection needs to be set to either PROT_READ or PROT_WRITE in the handler. However, when I try to inject instructions with mmap, and then use mprotect to set it to PROT_READ only, and then I execute the instructions via inline assembly, it causes a SIGSEGV as intended, but the handler is unable to get the originating address causing the signal, so I am unable to mprotect it to PROT_READ | PROT_EXEC.
Example:
void sigHandler(int signum, siginfo_t *info, void *ptr) {
printf("Received signal number: %d\n", signum);
printf("Signal originates from process %lu\n",
(unsigned long)info->si_pid);
printf("SIGSEGV caused by this address: ? %p\n", info->si_addr);
char * alignedbaseAddr = (((unsigned int)(info->si_addr)) >> 12) * getPageSize();
printf("Aligning to %p\n", alignedbaseAddr);
//flip this page to be r+x
mprotect(alignedbaseAddr, getPageSize(), PROT_READ | PROT_EXEC);
}
void setupSignalHandler() {
action.sa_sigaction = sigHandler;
action.sa_flags = SA_SIGINFO;
sigemptyset(&action.sa_mask);
sigaction(SIGSEGV, &action, NULL);
}
int main(int argc, char *argv[]) {
char * baseAddr = (char*)mmap(NULL, getDiskSize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(baseAddr == MAP_FAILED) {
perror("Unable to mmap.");
}
printf("Process address space is %d\n", getDiskSize());
//no-op filler
for(int i = 0; i < (getDiskSize()) - 1; i++) {
baseAddr[i] = 0x90;
}
//ret instruction
baseAddr[i] = 0xc3;
if( mprotect(baseAddr, getDiskSize(), PROT_READ) == -1) {
perror("mprotect");
exit(1);
}
printf("Protecting addresses: %p to %p for READ_ONLY\n", baseAddr, baseAddr + getDiskSize() - 1);
setupSignalHandler();
__asm__
(
"call %%eax;"
: "=a" (output)
: "a" (baseAddr)
);
printf("Will this ever print?");
//close fd, and unmap memory
cleanUp();
return EXIT_SUCCESS;
}
Here is the resulting output:
Received signal number: 11
Signal originates from process 0
SIGSEGV caused by this address: ? (nil)
//the above output repeatedly loops, since it fails to "re mprotect" that page.
Architecture:
x86 32 bit
OS:
Ubuntu 11.04 - Linux version 2.6.38-12-generic (buildd#vernadsky) (gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) )
Any ideas? The above logic works fine for simply read and writing into memory. Is there
a better way to execute instructions at runtime as opposed to inline assembly?
Thanks in advance!
In that case, the faulting address is the instruction pointer. Cast your third argument ptr (of your signal handler installed with SA_SIGINFO) to a ucontext_t, and retrieve the appropriate register, perhaps as (untested code!)
ucontext_t *uc = ptr;
void* faultyip = uc->uc_mcontext.gregs[REG_IP];
Read carefully /usr/include/sys/ucontext.h for more.
I'm interested to know why you are asking!!

got error 1314 when doing SetTokenInformation

#include <windows.h>
#include <stdio.h>
#include <Userenv.h>
#include <Wtsapi32.h>
int main() {
DWORD err;
err=GetLastError();
printf( "err001:%d\n",err);
HANDLE hTokenThis = NULL;
HANDLE hTokenDup = NULL;
HANDLE hThisProcess = GetCurrentProcess();
OpenProcessToken(hThisProcess, TOKEN_ALL_ACCESS, &hTokenThis);
err=GetLastError();
printf( "err002:%d\n",err);
DuplicateTokenEx(hTokenThis, MAXIMUM_ALLOWED,NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
err=GetLastError();
printf( "err003:%d\n",err);
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
WTSQueryUserToken(dwSessionId, hTokenDup);
//DWORD dwSessionId = 1;
SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD));
err=GetLastError();
printf( "err004:%d\n",err);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "WinSta0\\Default";
LPVOID pEnv = NULL;
DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE);
err=GetLastError();
printf( "err005:%d\n",err);
CreateProcessAsUser(
hTokenDup,
NULL,
(char *)"notepad",
NULL,
NULL,
FALSE,
dwCreationFlag,
pEnv,
NULL,
&si,
&pi);
printf("here we go\n");
err=GetLastError();
printf( "err006:%d\n",err);
return 0;
}
Compile:
gcc -o session.exe session.c c://Windows/System32/kernel32.dll c://Window
s/System32/wtsapi32.dll -lUserenv
Running Result:
session.exe
err001:126
err002:126
err003:126
err004:1314
err005:203
here we go
err006:87
gcc version 4.5.2 (GCC) from mingw.
btw, just ignore the error 126.
My question is :
Why got error 1314?
I want to start a program in the interactive desktop from service by using CreateProcessAsUser without knowing the logon user and password.
Error 1314 is "A required privilege is not held by the client".
From the WTSQueryUserToken() docs (http://msdn.microsoft.com/en-us/library/aa383840.aspx):
To call this function successfully, the calling application must be running within the context of the LocalSystem account and have the SE_TCB_NAME privilege
Also your call to WTSQueryUserToken() should look like:
WTSQueryUserToken(dwSessionId, &hTokenDup);
And you'll need appropriate privileges for SetTokenInformation() enabled as well.
Bottom line is that you're trying to do something that Windows reserves for highly privileged processes, so you'll need to make sure your process is configured to run appropriately (maybe as a service that talks to a regular non-privileged process for user interaction).

Resources