How can I get the Primary access token in windows 8? - windows

I want to get the primary token so that I can get the access of OpenInputDesktop() and do my necessary things.
I browsed all over the sites for help and found the conclusive code as below but I got an error on calling DuplicateTokenEx() is 998 which means invalid access to memory location.
HANDLE GetCurrentUserToken()
{
HANDLE currentToken = 0;
PHANDLE primaryToken = 0;
unsigned int winlogonPid = 0;
int dwSessionId = 0;
PHANDLE hUserToken = 0;
PHANDLE hTokenDup = 0;
PWTS_SESSION_INFO pSessionInfo = 0;
DWORD dwCount = 0;
WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1,
&pSessionInfo, &dwCount);
//TestLog("Error on WTSEnumerateSessions(): %d",GetLastError());
int dataSize = sizeof(WTS_SESSION_INFO);
for (DWORD i = 0; i < dwCount; ++i)
{
WTS_SESSION_INFO si = pSessionInfo[i];
if (WTSActive == si.State)
{
dwSessionId = si.SessionId;
break;
}
}
WTSFreeMemory(pSessionInfo);
array<Process^>^localByName = Process::GetProcessesByName( "winlogon" );
for (int i=0;i<localByName->Length;i++)
{
Process ^ p1 = (Process^)(localByName->GetValue(i));
if ((unsigned int)p1->SessionId == dwSessionId)
{
winlogonPid = (unsigned int)p1->Id;
}
}
// obtain a handle to the winlogon process
HANDLE hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);
TestLog("Error on OpenProcess():",GetLastError());
// obtain a handle to the access token of the winlogon process
if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE, &currentToken))
{
TestLog("Error on OpenProcessToken():",GetLastError());
CloseHandle(hProcess);
return false;
}
BOOL bRet ;
// bRet = DuplicateTokenEx(currentToken,
// MAXIMUM_ALLOWED /*TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS*/,
// NULL/*0*/,
// SecurityImpersonation, TokenImpersonation, primaryToken);
bRet = DuplicateTokenEx(currentToken,
TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS,
NULL, SecurityImpersonation,
TokenPrimary, primaryToken);
TestLog("Error on DuplicateTokenEx():",GetLastError());
TestLog("return value of DuplicateTokenEx()",bRet);
int errorcode = GetLastError();
if (bRet == false)
{
return 0;
}
return primaryToken;
}
int main(array<System::String ^> ^args)
{
Console::WriteLine(L"Hello World");
TestLog("**Start TestLaunchExeOneTime**",0);
HANDLE hTokenNew = NULL, hTokenDup = NULL;
HMODULE hmod = LoadLibrary(L"kernel32.dll");
hTokenDup = GetCurrentUserToken();
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si,0,sizeof(STARTUPINFO));
si.cb = sizeof( STARTUPINFO );
si.lpDesktop = L"winsta0\\default";
LPVOID pEnv = NULL;
DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
HMODULE hModule = LoadLibrary(L"Userenv.dll");
if(hModule )
{
if(CreateEnvironmentBlock(&pEnv,hTokenDup,FALSE))
{
//WriteToLog("CreateEnvironmentBlock Ok");
dwCreationFlag |= CREATE_UNICODE_ENVIRONMENT;
}
else
{
TestLog("Error on CreateEnvironmentBlock():",GetLastError());
pEnv = NULL;
}
}
//
if ( !CreateProcessAsUser( hTokenDup,
NULL,
L"C:\\temp\\DesktopDuplicationmilliseconds.exe",
NULL,
NULL,
FALSE,
dwCreationFlag,
pEnv,
NULL,
&si,
&pi
))
{
}
else
{
TestLog("Error on CreateProcessAsUser():",GetLastError());
// printf("error : %d",GetLastError());
}
return 0;
}

You haven't allocated any memory for the primary token. The primaryToken variable is a pointer to a handle, but you haven't actually pointed it to anything. (You've also declared GetCurrentUserToken as a function that returns a handle, but are actually returning a pointer to a handle.)
You need to either explicitly allocate the memory for the handle:
primaryToken = malloc(sizeof(HANDLE));
[...]
return *primaryToken;
or, more sensibly, define primaryToken as a HANDLE rather than a pointer and pass a reference to it in the appropriate place:
HANDLE primaryToken;
[...]
bRet = DuplicateTokenEx(currentToken,
TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS,
NULL, SecurityImpersonation,
TokenPrimary, &primaryToken);

Related

Error creating a screenshot in the winapi service

I have a client application written in C++, and a server written in Python. This application has several functions, including getting a screenshot of the client's desktop and getting this file on the server.
When I run these programs without any add-ons, everything works. I need to upload my client to the service, and I do it through CreateProcess[client file] inside of my service. All other functions besides the screenshot work with this approach.
Server code, getting a screenshot:
if (cState == State.GETTING_SCREENSHOT):
message = "SCREENSHOT".encode('utf-8')
MySend(client_sock , message)
curr_number = 0
with open("settings.txt" , 'r') as settings:
curr_number_str = settings.readline()
curr_number = int(curr_number_str)
with open("settings.txt" , 'w') as settings:
settings.write(str(curr_number + 1))
screenshot_file = str(curr_number) + ".png"
with open(screenshot_file , 'wb') as file:
while True:
data = MyRecv(client_sock , 40000)
data_arr = bytearray(data)
if (data_arr[:10] == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'):
continue
if (b'ENDOFF' in data):
break
file.write(data)
cState = State.INPUT_COMMAND
Client code:
case SENDING_SCREENSHOT_IN_PROGRESS:
{
wchar_t PathToLocalAppDataFolder[MAX_PATH];
if (FAILED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, PathToLocalAppDataFolder))) {
LoadMessage("Error in ShGetFolderPathW");
break;
}
std::wstring PathToScreenshot = std::wstring(PathToLocalAppDataFolder) + L"\\1.png";
if (!SaveScreen(PathToScreenshot.c_str())) {
LoadMessage("SaveScreen api-func failed");
break;
}
HANDLE hFile = CreateFile(PathToScreenshot.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
LoadMessage("Can not open screenshot file");
break;
}
DWORD dwRead = 1;
BYTE buffSend[BIG_BUFFLEN];
while (dwRead) {
ZeroMemory(buffSend, BIG_BUFFLEN);
dwRead = 0;
ReadFile(hFile, buffSend, BIG_BUFFLEN, &dwRead, NULL);
MySend(ClientSoc, (char*)buffSend, dwRead, 0);
}
CloseHandle(hFile);
char message[SMALL_BUFFLEN] = "ENDOFFILE";
MySend(ClientSoc, message, BIG_BUFFLEN, 0);
DeleteFile(PathToScreenshot.c_str());
cState = WAITING_FOR_INCOMING_COMMAND;
break;
}
Service code:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
#include <shlobj_core.h>
#include <string>
#include "api.h"
#include <fstream>
#pragma comment(lib , "API.lib")
#pragma warning(disable:4996)
wchar_t SERVICE_NAME[] = L"RemoteController";
bool isCreate = FALSE;
SERVICE_STATUS ServiceStatus = { 0 };
SERVICE_STATUS_HANDLE hServiceStatus; //StatusHandle
HANDLE ServiceStopEvent = INVALID_HANDLE_VALUE;
VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode);
DWORD WINAPI ServiceWorkerThreadEntry(LPVOID lpParam);
VOID Install(VOID);
BOOL dirExists(const wchar_t* dir_path);
int main(int argc, char* argv[]) {
FreeConsole();
Install();
SERVICE_TABLE_ENTRY ServiceTable[] = {
{SERVICE_NAME , (LPSERVICE_MAIN_FUNCTION)ServiceMain} ,
{NULL , NULL}
};
if (StartServiceCtrlDispatcher(ServiceTable) == FALSE) {
LoadMessage("Service.exe : StartServiceCtrlDIspathcer error");
return GetLastError();
}
return 0;
}
VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv) {
DWORD Status = E_FAIL;
hServiceStatus = RegisterServiceCtrlHandler(
SERVICE_NAME,
ServiceCtrlHandler
);
if (hServiceStatus == NULL) {
LoadMessage("Service.exe : RegisterServiceCtrlHandler failed");
return;
}
ZeroMemory(&ServiceStatus, sizeof(ServiceStatus));
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
if (SetServiceStatus(hServiceStatus, &ServiceStatus) == FALSE) {
LoadMessage("Service.exe : SetServiceStatus failed");
}
ServiceStopEvent = CreateEventW(NULL, TRUE, FALSE, L"RemoteControllerEvent");
if (ServiceStopEvent == NULL) {
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = GetLastError();
ServiceStatus.dwCheckPoint = 1;
if (SetServiceStatus(hServiceStatus, &ServiceStatus) == FALSE) {
LoadMessage("Service.exe : SetServiceStatus failed");
return;
}
}
//start
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
if (SetServiceStatus(hServiceStatus, &ServiceStatus) == FALSE) {
LoadMessage("Service.exe : SetServiceStatus failed");
}
HANDLE hThread = CreateThread(NULL, 0, ServiceWorkerThreadEntry, NULL, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(ServiceStopEvent);
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 3;
if (!SetServiceStatus(hServiceStatus, &ServiceStatus) == FALSE) {
LoadMessage("Service.exe : SetServiceStatus failed");
}
return;
}
VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode) {
switch (CtrlCode) {
case SERVICE_CONTROL_STOP:
if (ServiceStatus.dwCurrentState != SERVICE_RUNNING) break;
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 4;
if (SetServiceStatus(hServiceStatus, &ServiceStatus) == FALSE) {
LoadMessage("Service.exe : SetServiceStatus failed");
return;
}
SetEvent(ServiceStopEvent);
default:
break;
}
}
BOOL dirExists(const wchar_t* dir_path) {
DWORD dwAttributes = GetFileAttributes(dir_path);
if (dwAttributes == INVALID_FILE_ATTRIBUTES) return FALSE;
if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) return TRUE;
return FALSE;
}
VOID Install(VOID) {
SC_HANDLE schSCManager;
SC_HANDLE schService;
wchar_t curr_path[MAX_PATH];
if (!GetModuleFileName(NULL, curr_path, MAX_PATH)) {
LoadMessage("Service.exe : GetModuleFilename failed");
return;
}
schSCManager = OpenSCManager(
NULL, NULL, SC_MANAGER_ALL_ACCESS
);
if (schSCManager == NULL) {
LoadMessage("Service.exe : OpenSCManager failed[with SC_MANAGER_ALL_ACCESS]");
return;
}
schService = CreateService(
schSCManager, SERVICE_NAME, SERVICE_NAME, SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
curr_path, NULL, NULL, NULL, NULL, NULL);
if (schService == NULL) {
LoadMessage("Service.exe : CreateService failed");
CloseServiceHandle(schSCManager);
return;
}
if (StartService(schService , 0 , NULL) == 0){
LoadMessage("Service.exe : Start service failed");
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
return;
}
LoadMessage("\tService instaled");
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
}
DWORD WINAPI ServiceWorkerThreadEntry(LPVOID lpParam) {
if (isCreate) {
return ERROR_SUCCESS;
}
isCreate = TRUE;
wchar_t ProgramToRun[MAX_PATH];
ZeroMemory(ProgramToRun , sizeof(ProgramToRun));
SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, 0, ProgramToRun);
std::wstring tmp = std::wstring(ProgramToRun) + L"\\RemoteController\\MainClient.exe";
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
CreateProcess(tmp.c_str(), NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
return ERROR_SUCCESS;
}

How to serialize credentials in smart card credential provider for a domain account for logon and unlock?

I am building a credential provider which works same like windows smart card credential provider i.e this works only with domain accounts. I am facing an issue when passing the credentials to Negotiate SSP and I am using microsoft base smart card crypto provider as CSP. I am getting The parameter is incorrect error on lock screen after entering pin.
GetSerialization
HRESULT CCredential::GetSerialization(
CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE* pcpgsr,
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs,
PWSTR* ppwszOptionalStatusText,
CREDENTIAL_PROVIDER_STATUS_ICON* pcpsiOptionalStatusIcon
)
{
UNREFERENCED_PARAMETER(ppwszOptionalStatusText);
UNREFERENCED_PARAMETER(pcpsiOptionalStatusIcon);
HRESULT hr;
WCHAR dmz[244] = L"demodomain";
PWSTR pwzProtectedPin;
hr = ProtectIfNecessaryAndCopyPassword(_rgFieldStrings[SFI_PIN], _cpus, _dwFlags, &pwzProtectedPin);
if (SUCCEEDED(hr))
{
KERB_CERTIFICATE_UNLOCK_LOGON kiul;
// Initialize kiul with weak references to our credential.
hr = UnlockLogonInit(dmz, _rgFieldStrings[SFI_USERNAME], pwzProtectedPin, _cpus, &kiul);
if (SUCCEEDED(hr))
{
PBASE_SMARTCARD_CSP_INFO pCspInfo = _pContainer->GetCSPInfo();
if (pCspInfo)
{
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcp;
hr = UnlockLogonPack(kiul, pCspInfo, &pcpcs->rgbSerialization, &pcpcs->cbSerialization);
_pContainer->FreeCSPInfo(pCspInfo);
if (SUCCEEDED(hr))
{
ULONG ulAuthPackage;
hr = RetrieveNegotiateAuthPackage(&ulAuthPackage);
if (SUCCEEDED(hr))
{
pcpcs->ulAuthenticationPackage = ulAuthPackage;
pcpcs->clsidCredentialProvider = CLSID_CProvider;
// At this point the credential has created the serialized credential used for logon
// By setting this to CPGSR_RETURN_CREDENTIAL_FINISHED we are letting logonUI know
// that we have all the information we need and it should attempt to submit the
// serialized credential.
*pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED;
}
else
{
PrintLn(WINEVENT_LEVEL_WARNING, L"RetrieveNegotiateAuthPackage not SUCCEEDED hr=0x%08x", hr);
}
}
else
{
PrintLn(WINEVENT_LEVEL_WARNING, L"UnlockLogonPack not SUCCEEDED hr=0x%08x", hr);
}
}
else
{
PrintLn(WINEVENT_LEVEL_WARNING, L"pCspInfo NULL");
}
}
else
{
PrintLn(WINEVENT_LEVEL_WARNING, L"UnlockLogonInit not SUCCEEDED hr=0x%08x", hr);
}
CoTaskMemFree(pwzProtectedPin);
}
else
{
PrintLn(WINEVENT_LEVEL_WARNING, L"ProtectIfNecessaryAndCopyPassword not SUCCEEDED hr=0x%08x", hr);
}
if (!SUCCEEDED(hr))
{
PrintLn(WINEVENT_LEVEL_WARNING, L"not SUCCEEDED hr=0x%08x", hr);
}
else
{
PrintLn(WINEVENT_LEVEL_WARNING, L"OK");
}
return hr;
}
UnlockLogonInit
HRESULT UnlockLogonInit(
PWSTR pwzDomain,
PWSTR pwzUsername,
PWSTR pwzPin,
CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus,
KERB_CERTIFICATE_UNLOCK_LOGON* pkiul
)
{
UNREFERENCED_PARAMETER(cpus);
KERB_CERTIFICATE_UNLOCK_LOGON kiul;
ZeroMemory(&kiul, sizeof(kiul));
KERB_CERTIFICATE_LOGON* pkil = &kiul.Logon;
HRESULT hr = UnicodeStringInitWithString(pwzDomain, &pkil->LogonDomainName);
if (SUCCEEDED(hr))
{
hr = UnicodeStringInitWithString(pwzUsername, &pkil->UserName);
if (SUCCEEDED(hr))
{
hr = UnicodeStringInitWithString(pwzPin, &pkil->Pin);
if (SUCCEEDED(hr))
{
// Set a MessageType based on the usage scenario.
pkil->MessageType = KerbCertificateLogon; //13
pkil->CspDataLength = 0;
pkil->CspData = NULL;
pkil->Flags = 0;
if (SUCCEEDED(hr))
{
// KERB_INTERACTIVE_UNLOCK_LOGON is just a series of structures. A
// flat copy will properly initialize the output parameter.
CopyMemory(pkiul, &kiul, sizeof(*pkiul));
}
}
}
}
return hr;
}
UnlockLogonPack
HRESULT UnlockLogonPack(
const KERB_CERTIFICATE_UNLOCK_LOGON& rkiulIn,
const PBASE_SMARTCARD_CSP_INFO pCspInfo,
BYTE** prgb,
DWORD* pcb
)
{
HRESULT hr;
const KERB_CERTIFICATE_LOGON* pkilIn = &rkiulIn.Logon;
// alloc space for struct plus extra for the three strings
DWORD cb = sizeof(rkiulIn) +
pkilIn->LogonDomainName.Length +
pkilIn->UserName.Length +
pkilIn->Pin.Length +
pCspInfo->dwCspInfoLen;
KERB_CERTIFICATE_UNLOCK_LOGON* pkiulOut = (KERB_CERTIFICATE_UNLOCK_LOGON*)CoTaskMemAlloc(cb);
if (pkiulOut)
{
ZeroMemory(&pkiulOut->LogonId, sizeof(LUID));
//
// point pbBuffer at the beginning of the extra space
//
BYTE* pbBuffer = (BYTE*)pkiulOut + sizeof(*pkiulOut);
KERB_CERTIFICATE_LOGON* pkilOut = &pkiulOut->Logon;
pkilOut->MessageType = pkilIn->MessageType;
pkilOut->Flags = pkilIn->Flags;
//
// copy each string,
// fix up appropriate buffer pointer to be offset,
// advance buffer pointer over copied characters in extra space
//
_UnicodeStringPackedUnicodeStringCopy(pkilIn->LogonDomainName, (PWSTR)pbBuffer, &pkilOut->LogonDomainName);
pkilOut->LogonDomainName.Buffer = (PWSTR)(pbBuffer - (BYTE*)pkiulOut);
pbBuffer += pkilOut->LogonDomainName.Length;
_UnicodeStringPackedUnicodeStringCopy(pkilIn->UserName, (PWSTR)pbBuffer, &pkilOut->UserName);
pkilOut->UserName.Buffer = (PWSTR)(pbBuffer - (BYTE*)pkiulOut);
pbBuffer += pkilOut->UserName.Length;
_UnicodeStringPackedUnicodeStringCopy(pkilIn->Pin, (PWSTR)pbBuffer, &pkilOut->Pin);
pkilOut->Pin.Buffer = (PWSTR)(pbBuffer - (BYTE*)pkiulOut);
pbBuffer += pkilOut->Pin.Length;
pkilOut->CspData = (PUCHAR) (pbBuffer - (BYTE*)pkiulOut);
pkilOut->CspDataLength = pCspInfo->dwCspInfoLen;
memcpy(pbBuffer,pCspInfo,pCspInfo->dwCspInfoLen);
*prgb = (BYTE*)pkiulOut;
*pcb = cb;
hr = S_OK;
}
else
{
hr = E_OUTOFMEMORY;
}
return hr;
}
_KERB_SMARTCARD_CSP_INFO Structure and GetCSPInfo
// based on _KERB_SMARTCARD_CSP_INFO
typedef struct _BASE_SMARTCARD_CSP_INFO
{
DWORD dwCspInfoLen;
DWORD MessageType;
union {
PVOID ContextInformation;
ULONG64 SpaceHolderForWow64;
} ;
DWORD flags;
DWORD KeySpec;
ULONG nCardNameOffset;
ULONG nReaderNameOffset;
ULONG nContainerNameOffset;
ULONG nCSPNameOffset;
TCHAR bBuffer[sizeof(DWORD)];
} BASE_SMARTCARD_CSP_INFO,
*PBASE_SMARTCARD_CSP_INFO;
PBASE_SMARTCARD_CSP_INFO CContainer::GetCSPInfo()
{
//szreaderName, szCardname, szproviderName, szContainerName are initialized with respective values in constructor
_ASSERTE( _CrtCheckMemory( ) );
DWORD dwReaderLen = (DWORD) _tcslen(_szReaderName)+1;
DWORD dwCardLen = (DWORD) _tcslen(_szCardName)+1;
DWORD dwProviderLen = (DWORD) _tcslen(_szProviderName)+1;
DWORD dwContainerLen = (DWORD) _tcslen(_szContainerName)+1;
DWORD dwBufferSize = dwReaderLen + dwCardLen + dwProviderLen + dwContainerLen;
PBASE_SMARTCARD_CSP_INFO pCspInfo = (PBASE_SMARTCARD_CSP_INFO) BASEAlloc(sizeof(BASE_SMARTCARD_CSP_INFO)+dwBufferSize*sizeof(TCHAR));
if (!pCspInfo) return NULL;
//ZeroMemory(pCspInfo);
memset(pCspInfo,0,sizeof(BASE_SMARTCARD_CSP_INFO));
pCspInfo->dwCspInfoLen = sizeof(BASE_SMARTCARD_CSP_INFO)+dwBufferSize*sizeof(TCHAR);
pCspInfo->MessageType = 1;
pCspInfo->KeySpec = _KeySpec;
pCspInfo->nCardNameOffset = ARRAYSIZE(pCspInfo->bBuffer);
pCspInfo->nReaderNameOffset = pCspInfo->nCardNameOffset + dwCardLen;
pCspInfo->nContainerNameOffset = pCspInfo->nReaderNameOffset + dwReaderLen;
pCspInfo->nCSPNameOffset = pCspInfo->nContainerNameOffset + dwContainerLen;
memset(pCspInfo->bBuffer,0,sizeof(pCspInfo->bBuffer));
_tcscpy_s(&pCspInfo->bBuffer[pCspInfo->nCardNameOffset] ,dwBufferSize + 4 - pCspInfo->nCardNameOffset, _szCardName);
_tcscpy_s(&pCspInfo->bBuffer[pCspInfo->nReaderNameOffset] ,dwBufferSize + 4 - pCspInfo->nReaderNameOffset, _szReaderName);
_tcscpy_s(&pCspInfo->bBuffer[pCspInfo->nContainerNameOffset] ,dwBufferSize + 4 - pCspInfo->nContainerNameOffset, _szContainerName);
_tcscpy_s(&pCspInfo->bBuffer[pCspInfo->nCSPNameOffset] ,dwBufferSize + 4 - pCspInfo->nCSPNameOffset, _szProviderName);
_ASSERTE( _CrtCheckMemory( ) );
return pCspInfo;
}
I don't understand where I am doing wrong, been stuck here for a while now. Any help would be appreciated.

Capture encrypted USB decryption event?

hi I am using a Kingston DT4000 G2 USB drive with password protected.
I could track disk plug in & out event under windows by calling RegisterDeviceNotification(),
and receive notification by WM_DEVICECHANGE;
While the problem is the media is not available till I input password.
Before decryption I could see the device and system will show "Please insert a disk into USB drive (E:)".
But I can't capture the event when data is decrypted and media is really available to me.
Is there a such event could be captured using win32?
You could use following sample with GetLockStatus method of the Win32_EncryptableVolume
#include <windows.h>
#include <dbt.h>
#include <string>
#include <initguid.h>
#include <IoEvent.h>
#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
using namespace std;
#pragma comment(lib, "wbemuuid.lib")
#pragma warning(disable : 4996)
// Function prototype
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
std::string DrivesFromMask(ULONG unitmask);
UINT32 GetLockStatus();
int main(int argc, char** argv)
{
MSG msg; // MSG structure to store messages
HWND hwndMain; // Main window handle
WNDCLASSEX wcx; // WINDOW class information
HDEVNOTIFY hDevnotify;
DWORD len;
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
// 53F56307-B6BF-11D0-94F2-00A0C91EFB8B
GUID FilterGUID = { 0x53F56307,0x0B6BF,0x11D0,{0x94,0xF2,0x00,0xA0,0xC9,0x1E,0xFB,0x8B} };
// Initialize the struct to zero
ZeroMemory(&wcx, sizeof(WNDCLASSEX));
wcx.cbSize = sizeof(WNDCLASSEX); // Window size. Must always be sizeof(WNDCLASSEX)
wcx.style = 0; // Class styles
wcx.lpfnWndProc = (WNDPROC)MainWndProc; // Pointer to the callback procedure
wcx.cbClsExtra = 0; // Extra byte to allocate following the wndclassex structure
wcx.cbWndExtra = 0; // Extra byte to allocate following an instance of the structure
wcx.hInstance = GetModuleHandle(NULL); // Instance of the application
wcx.hIcon = NULL; // Class Icon
wcx.hCursor = NULL; // Class Cursor
wcx.hbrBackground = NULL; // Background brush
wcx.lpszMenuName = NULL; // Menu resource
wcx.lpszClassName = "USB"; // Name of this class
wcx.hIconSm = NULL; // Small icon for this class
// Register this window class with MS-Windows
if (!RegisterClassEx(&wcx))
return 0;
// Create the window
hwndMain = CreateWindowEx(0,// Extended window style
"USB", // Window class name
"", // Window title
WS_POPUP, // Window style
0, 0, // (x,y) pos of the window
0, 0, // Width and height of the window
NULL, // HWND of the parent window (can be null also)
NULL, // Handle to menu
GetModuleHandle(NULL), // Handle to application instance
NULL); // Pointer to window creation data
// Check if window creation was successful
if (!hwndMain)
return 0;
// Make the window invisible
ShowWindow(hwndMain, SW_HIDE);
// Initialize device class structure
len = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
memset(&NotificationFilter, 0, len);
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = 5; // DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = FilterGUID;
// Register
hDevnotify = RegisterDeviceNotification(hwndMain, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
if (hDevnotify == NULL)
return 0;
// Process messages coming to this window
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// return value to the system
return msg.wParam;
}
HDEVNOTIFY RegisterDevice(HWND hWnd, PDEV_BROADCAST_DEVICEINTERFACE PdevDEVICEINTERFACE)
{
DEV_BROADCAST_HANDLE broadcast = { 0 };
broadcast.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
broadcast.dbch_devicetype = DBT_DEVTYP_HANDLE;
broadcast.dbch_handle = CreateFile(PdevDEVICEINTERFACE->dbcc_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
return RegisterDeviceNotification(hWnd, &broadcast, DEVICE_NOTIFY_WINDOW_HANDLE);
}
HDEVNOTIFY hDevNotify = NULL;
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PDEV_BROADCAST_VOLUME PdevVolume;
PDEV_BROADCAST_DEVICEINTERFACE PdevDEVICEINTERFACE;
std::string drvs;
static UINT32 g_LockedDrivesMask;
switch (msg)
{
case WM_DEVICECHANGE:
switch (wParam)
{
// A device or piece of media has been inserted and is now available
case DBT_CUSTOMEVENT:
{
DEV_BROADCAST_HDR* hdr = (DEV_BROADCAST_HDR*)lParam;
switch (hdr->dbch_devicetype)
{
case DBT_DEVTYP_HANDLE:
UINT32 LockedDrivesMask = GetLockStatus();
UINT32 result = LockedDrivesMask ^ g_LockedDrivesMask;
if (result)
{
for (int i = 0; i < 26 && result; ++i)
{
if (result & 0x1)
{
if (0 == (LockedDrivesMask & (0x1 << i)))
printf("%c: unlock!\n", i + 'A');
}
result = result >> 1;
}
}
g_LockedDrivesMask = LockedDrivesMask;
break;
}
}
break;
case DBT_DEVICEARRIVAL:
PdevDEVICEINTERFACE = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
switch (PdevDEVICEINTERFACE->dbcc_devicetype)
{
// Class of devices
case DBT_DEVTYP_DEVICEINTERFACE:
g_LockedDrivesMask = GetLockStatus();
hDevNotify = RegisterDevice(hwnd, PdevDEVICEINTERFACE);
break;
// Logical volume
case DBT_DEVTYP_VOLUME:
PdevVolume = (PDEV_BROADCAST_VOLUME)lParam;
drvs = DrivesFromMask(PdevVolume->dbcv_unitmask);
for (UINT i = 0; i < drvs.length(); i++)
printf("Drive %c:\\ connected\n", drvs[i]);
}
break;
case DBT_DEVICEREMOVEPENDING:
PdevDEVICEINTERFACE = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
UnregisterDeviceNotification(hDevNotify);
}
break;
default:
// Call the default window handler
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
std::string DrivesFromMask(ULONG unitmask)
{
char i;
std::string drv = "";
for (i = 0; i < 26 && unitmask; ++i)
{
if (unitmask & 0x1)
{
drv += i + 'A';
}
unitmask = unitmask >> 1;
}
return drv;
}
UINT32 GetLockStatus()
{
HRESULT hres;
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
hres = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL
);
IWbemLocator* pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID*)&pLoc);
IWbemServices* pSvc = NULL;
hres = pLoc->ConnectServer(
_bstr_t(L"Root\\CIMV2\\Security\\MicrosoftVolumeEncryption"), // Object path of WMI namespace
NULL,
NULL,
0,
NULL,
0,
0,
&pSvc
);
hres = CoSetProxyBlanket(
pSvc,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE
);
IEnumWbemClassObject* pEnumerator = NULL;
wstring strQuery = L"SELECT * FROM Win32_EncryptableVolume";
hres = pSvc->ExecQuery(BSTR(L"WQL"), BSTR(strQuery.c_str()),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
IWbemClassObject* pclsObj = NULL;
IWbemClassObject* pOutParams = NULL;
ULONG uReturn = 0;
UINT32 mask = 0;
while (pEnumerator)
{
UINT32 bit = 0;
hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (0 == uReturn || FAILED(hres))
break;
IWbemClassObject* pClass = NULL;
hres = pSvc->GetObject(BSTR(L"Win32_EncryptableVolume"), 0, NULL, &pClass, NULL);
VARIANT val;
hres = pclsObj->Get(L"DriveLetter", 0, &val, 0, NULL);
bit = val.bstrVal[0] - 'A';
IWbemClassObject* pInParamsDefinition = NULL;
hres = pClass->GetMethod(L"GetLockStatus", 0, NULL, NULL);
VARIANT var;
pclsObj->Get(L"__PATH", 0, &var, NULL, NULL);
hres = pSvc->ExecMethod(var.bstrVal, _bstr_t(L"GetLockStatus"), 0,
NULL, NULL, &pOutParams, NULL);
VARIANT varReturnValue;
hres = pOutParams->Get(_bstr_t(L"LockStatus"), 0,
&varReturnValue, NULL, 0);
if (varReturnValue.iVal)
{
mask |= 0x1 << bit;
}
VariantClear(&val);
VariantClear(&var);
VariantClear(&varReturnValue);
pclsObj->Release();
pClass->Release();
pOutParams->Release();
pOutParams = NULL;
}
pEnumerator->Release();
pLoc->Release();
pSvc->Release();
CoUninitialize();
return mask;
}
But please note that due to the Security Considerations, this sample must be run as admin.
Or without administrator privileges, you could use the polling method in this example:
https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/e0585eca-31fa-4fe4-873d-d87934cbbf9d/thread-not-working-if-winmain-arg-is-2?forum=windowssdk

Hide a process from Task Manager

I'm trying to hide a process from the taskmanager but it doesn't work .
I dont understand why ...
Thank you for your help in advance... !
This is my function who inject the hider_dll.dll :
int Inject(char* dll)
{
int pid = getpid();
HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,false,pid);
if(hProc)
{
cout<<"OpenProcess success"<<endl;
}
else
{
cout<<"OpenProcess failed..."<<endl;
return 0;
}
LPVOID Vmem=VirtualAllocEx(hProc,0,strlen(dll)+1,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
DWORD wrt;
WriteProcessMemory(hProc,Vmem,dll,strlen(dll),(SIZE_T*)&wrt);
stringstream sstr;
sstr << wrt;
string str = sstr.str();
cout<<"Writed "+str+" bytes"<<endl;
FARPROC LoadLib=GetProcAddress(LoadLibrary(L"kernel32.dll"),"LoadLibraryA");
HANDLE h=CreateRemoteThread(hProc,0,0,(LPTHREAD_START_ROUTINE)LoadLib,Vmem,0,0);
if(h)
{
cout<<"CreateRemoteThread success"<<endl;
}
else
{
cout<<"CreateRemoteThread failed\r\nError:"<<GetLastError()<<endl;
return 0;
}
WaitForSingleObject(h,INFINITE);
DWORD exit;
GetExitCodeThread(h,&exit);
cout<<"Dll loaded to "<<exit<<endl;
return 1;
}
Here is a proper injector:
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
DWORD GetProcId(const char* procName)
{
DWORD procId = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32First(hSnap, &procEntry))
{
do
{
if (!_stricmp(procEntry.szExeFile, procName))
{
procId = procEntry.th32ProcessID;
break;
}
} while (Process32Next(hSnap, &procEntry));
}
}
CloseHandle(hSnap);
return procId;
}
int main()
{
const char* dllPath = "C:\\Users\\'%USERNAME%'\\Desktop\\dll.dll"; //
const char* procName = "processname.exe"; //
DWORD procId = 0;
while (!procId)
{
procId = GetProcId(procName);
Sleep(30);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, procId);
if (hProc && hProc != INVALID_HANDLE_VALUE)
{
void* loc = VirtualAllocEx(hProc, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProc, loc, dllPath, strlen(dllPath) + 1, 0);
HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, loc, 0, 0);
if (hThread)
{
CloseHandle(hThread);
}
}
if (hProc)
{
CloseHandle(hProc);
}
return 0;
}
To hide processes from Task Manager you need to hook NtQuerySystemInformation() and if the argument SYSTEM_PROCESS_INFORMATION is used, you need to remove your process from the linked list of processes.
This is what your hook would look like:
// Hooked function
NTSTATUS WINAPI HookedNtQuerySystemInformation(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__inout PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength
)
{
NTSTATUS status = OriginalNtQuerySystemInformation(SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength);
if (SystemProcessInformation == SystemInformationClass && STATUS_SUCCESS == status)
{
// Loop through the list of processes
PMY_SYSTEM_PROCESS_INFORMATION pCurrent = NULL;
PMY_SYSTEM_PROCESS_INFORMATION pNext = (PMY_SYSTEM_PROCESS_INFORMATION)
SystemInformation;
do
{
pCurrent = pNext;
pNext = (PMY_SYSTEM_PROCESS_INFORMATION)((PUCHAR)pCurrent + pCurrent->
NextEntryOffset);
if (!wcsncmp(pNext->ImageName.Buffer, L"notepad.exe", pNext->ImageName.Length))
{
if (!pNext->NextEntryOffset)
{
pCurrent->NextEntryOffset = 0;
}
else
{
pCurrent->NextEntryOffset += pNext->NextEntryOffset;
}
pNext = pCurrent;
}
} while (pCurrent->NextEntryOffset != 0);
}
return status;
}

Can I Write Version Information API For Both CHAR And WCHAR?

I'm a little bit short of reaching my goal.
GetFileVersionInfoSize() is working fine along with other two functions GetFileVersionInfo() and VerQueryValue(). I would like to just add more features to it to make it complete.
I've coded it to run on WCHAR and would like to know making it run for CHAR would make sense?
Is there a way around it so that I code it once and it would work for both?
Also, is there a way I could enumerate the contents of \\StringFileInfo\\lang-codepage\\* ?
DWORD GetFileVersionInfo3(const TCHAR *pszFilePath, std::vector<std::pair<std::wstring, std::wstring>> *lplist)
{
DWORD dwSize = 0;
BYTE *pbVersionInfo = NULL;
VS_FIXEDFILEINFO *pFileInfo = NULL;
UINT puLenFileInfo = 0;
dwSize = GetFileVersionInfoSize(pszFilePath, NULL);
if (dwSize == 0)
{
printf("\nError in GetFileVersionInfoSize: %d\n", GetLastError());
return 1;
}
pbVersionInfo = new BYTE[dwSize];
memset(pbVersionInfo, '\0', dwSize);
if (!GetFileVersionInfo(pszFilePath, 0, dwSize, pbVersionInfo))
{
printf("\nError in GetFileVersionInfo: %d\n", GetLastError());
delete[] pbVersionInfo;
return 1;
}
if (!VerQueryValue(pbVersionInfo, TEXT("\\"), (LPVOID*)&pFileInfo, &puLenFileInfo))
{
printf("\nError in VerQueryValue: %d\n", GetLastError());
delete[] pbVersionInfo;
return 1;
}
if (!VerQueryValue(pbVersionInfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &puLenFileInfo))
{
printf("\nError in VerQueryValue: %d\n", GetLastError());
return 1;
}
std::vector<std::wstring>::iterator itr;
std::vector<std::wstring> wlist;
wlist.clear();
wlist.push_back(L"FileDescription");
wlist.push_back(L"InternalName");
wlist.push_back(L"OriginalFilename");
wlist.push_back(L"CompanyName");
wlist.push_back(L"FileVersion");
wlist.push_back(L"ProductName");
wlist.push_back(L"ProductVersion");
wlist.push_back(L"LegalCopyright");
char fileEntry[1024];
for (int i = 0; i < (puLenFileInfo / sizeof(struct LANGANDCODEPAGE)); i++)
{
sprintf_s(fileEntry, 1024, "\\StringFileInfo\\%04x%04x\\",
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage);
lplist->push_back(std::pair<std::wstring, std::wstring>(L"File: ", pszFilePath));
std::string s1(fileEntry);
for (itr = wlist.begin(); itr != wlist.end(); itr++)
{
std::wstring item = *itr;
std::wstring wstr;
wstr.append(s1.begin(), s1.end());
wstr.append(item);
LPVOID lpBuffer = NULL;
UINT dwBytes = 0;
bool bRes = VerQueryValue(pbVersionInfo, wstr.c_str(), (LPVOID*)&lpBuffer, &dwBytes);
if (!bRes)
{
continue;
}
LPTSTR wsResult;
wsResult = (LPTSTR)lpBuffer;
lplist->push_back(std::pair<std::wstring, std::wstring>(item, wsResult));
}
}
return 0;
}
Since you are using TCHAR, use std:::basic_string<TCHAR> instead of std::wstring to match. Otherwise, drop TCHAR and use WCHAR for everything.

Resources