Trying to make a simple program that open a webpage when executed but I'm getting a parse error, and I don't know why.
#include <windows.h>
#include <shellapi.h>
bool open_browser()
{
HINSTANCE result = ShellExecuteA( HWND, "open", "http://www.reddit.com",
NULL, NULL, SW_SHOWNORMAL );
// Return whether or not we were successful.
return (result);
}
int main( )
{
open_browser();
return 0;
}
HWND is a type, not a value, so it's invalid as a function argument.
you are passing a type, instead you should pass an instance of the HWND type
HWND myhwnd = ::CreateWindowA("STATIC", "reddit", WS_VISIBLE, 0, 0, 400, 600, NULL, NULL, NULL, NULL);
HINSTANCE result = ShellExecuteA(myhwnd, "open", "http://www.reddit.com", NULL, NULL, SW_SHOWNORMAL);
Related
I am trying to write to my Windows 10 registry, to include a program in Startup.
At the moment I have written the following code, which is not wroking:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winnt.h>
#include <winreg.h>
int main()
{
const TCHAR* path = TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
LPDWORD holdResult;
PHKEY hKey;
int lResult;
//lResult = RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_READ, &hKey);
lResult = RegCreateKeyExA(HKEY_CURRENT_USER, "myprogram", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &holdResult);
if (lResult != ERROR_SUCCESS)
{
if (lResult == ERROR_FILE_NOT_FOUND) {
printf("Key not found.\n");
return TRUE;
}
else {
printf("Error opening key.\n");
return FALSE;
}
}
printf("Key already existed or not: %p\n", holdResult);
char* szPath = "C:\\Users\\Myname\\Documents\\coolprogram.exe";
lResult = RegSetValueExA(hKey, "program", 0, REG_SZ,(LPBYTE)szPath, sizeof(wchar_t)*(wcslen(szPath)+1));
printf("Key successfully set or not: %d\n", lResult);
RegCloseKey(hKey);
return 0;
}
The strange thing is, although the code does not write anything to the registry, I get no error message, and the program executes as successful!
This is what gets printed to the terminal when I run the code:
Key already existed or not: 0000000000000002
Key successfully set or not: 0
So, the key had already been previously created, and was succesfully set, which did not happen, there is nothing in my registry.
I believe this is a permissions problem, because for some reason I cannot alter my registry permissions manually, even after setting myself as owner, it is impossible for me to allow "Full Control" to myself.
But I expected some sort of error, such as "ACCESS DENIED: INSUFFICIENT PERMISSIONS", but I am getting a success. Strange.
You are passing the wrong key path to RegCreateKeyEx(). You are trying to write your program value to HKCU\myprogram rather than to HKCU\SOFTWARE\Microsoft\...\Run.
You are also passing invalid pointers to RegCreateKeyEx(). Its last 2 parameters expect pointers to HKEY and DWORD variables, but you are passing in pointers to HKEY* and DWORD* variables instead.
You are also passing an incorrect parameter to RegSetValueExA(), too. You are giving it an ANSI string (OK, since it is an ANSI function), but are passing in a Unicode string length that is 2x the byte size of the actual ANSI string (bad).
In fact, your code shouldn't even compile as shown.
Try this instead:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winnt.h>
#include <winreg.h>
int main()
{
const char* szKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
const char* szPath = "C:\\Users\\Myname\\Documents\\coolprogram.exe";
DWORD dwDisposition;
HKEY hKey;
LSTATUS lResult;
//lResult = RegOpenKeyExA(HKEY_CURRENT_USER, szKey, 0, KEY_QUERY_VALUE, &hKey);
lResult = RegCreateKeyExA(HKEY_CURRENT_USER, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, &dwDisposition);
if (lResult != ERROR_SUCCESS)
{
printf("Error creating key: %ld\n", lResult);
return 0;
}
printf("Key already existed or not: %lu\n", dwDisposition);
lResult = RegSetValueExA(hKey, "program", 0, REG_SZ, (LPBYTE)szPath, sizeof(TCHAR)*(strlen(szPath)+1));
printf("Key successfully set or not: %ld\n", lResult);
RegCloseKey(hKey);
return 0;
}
I have a console application which calls the CreateProcessWithTokenW() WinAPI function to create a new process which starts a cmd console. By calling it, it starts a new CMD Window. I want to spawn another cmd within the calling cmd window (not in a new window).
So I want to simulate the same behavior like if you start cmd and type "cmd".
ret = CreateProcessWithTokenW(pNewToken, 0, L"C:\\Windows\\System32\\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
Here is a minimal reproducible code snippet.
I added CreateProcess instead of CreateProcessWithToken....if i define 0 for 5th argument (dwCreationFlag) than it starts the CMD in the Powershell. But for CreateProcessWithToken the behavior is not the same.
Run this code with a elevated powershell (because it needs Se_Debug_Priv)
#include <stdio.h>
#include <Windows.h>
#include <WinBase.h>
#include <iostream>
#include <tchar.h>
int main() {
//DEFINE HERE PID OF winlogon.exe
DWORD pid = 940;
HANDLE currentProcess = {};
HANDLE AccessToken = {};
currentProcess = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, pid);
OpenProcessToken(currentProcess, TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY, &AccessToken);
HANDLE pToken = AccessToken;
SECURITY_IMPERSONATION_LEVEL seImpersonateLevel = SecurityImpersonation;
TOKEN_TYPE tokenType = TokenPrimary;
HANDLE pNewToken = new HANDLE;
DuplicateTokenEx(pToken, MAXIMUM_ALLOWED, NULL, seImpersonateLevel, tokenType, &pNewToken);
STARTUPINFO si = {};
PROCESS_INFORMATION pi = {};
//TEST1
//Creates a new window for both functions so the 5th seems to be ignored
CreateProcessWithTokenW(pNewToken, 0, L"C:\\Windows\\System32\\cmd.exe", NULL, 0, NULL, NULL, &si, &pi);
CreateProcessWithTokenW(pNewToken, 0, L"cmds.bat", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
//TEST2
//Create a new windows, assumed behavior
CreateProcessW(L"C:\\Windows\\System32\\cmd.exe", NULL, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
//Creates also a new window, NOT assumed behavior
CreateProcessW(L"C:\\Windows\\System32\\cmd.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
return 0;
}
Get rid of the CREATE_NEW_CONSOLE flag:
CREATE_NEW_CONSOLE
0x00000010
The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS flag.
This flag is enabled by default.
That flash is what is forcing a new CMD window to be created. Without that, the new process will be created in the existing CMD window of the calling process.
As far as I'm concerned, you should use CREATE_NEW_CONSOLE. According to the code:
ret = CreateProcessWithTokenW(pNewToken, 0, L"C:\\Windows\\System32\\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
The problem is not with the use of CreateProcessWithTokenW () winapi. Could you please provide us with a minimal reproducible exampleto reproduce the issue.
Here is the code:
STARTUPINFOEX startup_info = {};
PROCESS_INFORMATION process_info = {};
BOOL CreateProcTokenRes = FALSE;
CreateProcTokenRes = CreateProcessWithTokenW(NewToken, 0, L"C:\\Windows\\system32\\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &process_info);
if (!CreateProcTokenRes)
{
_tprintf(L"Cannot Create Process With Token. Failed with Error Code: %d\n", GetLastError());
CloseHandle(NewToken);
For more details I suggest you could refer to the link:https://niiconsulting.com/checkmate/2019/11/token-manipulation-attacks-part-2-process-of-impersonation/
I've tried to load a bmp image using LoadImage() in order to display it, but I just can't find a way to load the image. Here is some code:
EDIT
as suggested, here is a runnable example
#include <windows.h>
#include <iostream>
#include <fstream>
std::string GetLastErrorAsString()
{
//Get the error message, if any.
DWORD errorMessageID = ::GetLastError();
if (errorMessageID == 0)
return std::string(); //No error message has been recorded
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
std::string message(messageBuffer, size);
//Free the buffer.
LocalFree(messageBuffer);
return message;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int iShow) {
std::ofstream file("output.txt");
HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, L"C:\\yes.bmp", IMAGE_BITMAP, 300, 300, LR_LOADFROMFILE);
if (hBitmap == NULL) {
file << "error: " << GetLastErrorAsString().c_str() << std::endl;
return 1;
}
else {
file << "success." << std::endl;
}
return 0;
}
And this result is always NULL. If I put a wrong file name, the error message will be The system cannot find the file specified. but if the name is right, there is simply no error message.
I've tried to save the bmp file in 24 and 32 bits, I played with the LR_ flags, it doesn't change anything.
I also tried setting the HINSTANCE to the main's one, without any success.
I run this code once at the beginning of the main.
Thanks for your help, I hope I just misunderstood how this works
Let's say I have very simple little code sample which uses async WinInet:
#include "stdafx.h"
#include "WinInet.h"
#pragma comment(lib, "wininet.lib")
DWORD LatestResult = 0;
HANDLE MayContinue = 0;
VOID CALLBACK
CallBack(
__in HINTERNET hInternet,
__in DWORD_PTR dwContext,
__in DWORD dwInternetStatus,
__in_bcount(dwStatusInformationLength) LPVOID lpvStatusInformation,
__in DWORD dwStatusInformationLength
)
{
if (dwInternetStatus == INTERNET_STATUS_REQUEST_COMPLETE)
{
LatestResult = ((LPINTERNET_ASYNC_RESULT)lpvStatusInformation)->dwResult;
SetEvent (MayContinue);
}
}
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
MayContinue = ::CreateEvent (NULL, FALSE, FALSE, NULL);
HINTERNET Session = InternetOpen (NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
INTERNET_STATUS_CALLBACK CallbackPointer = InternetSetStatusCallback (Session, (INTERNET_STATUS_CALLBACK) CallBack);
MayContinue = ::CreateEvent (NULL, FALSE, FALSE, NULL);
InternetConnect (Session, _T ("ftp.secureftp-test.com"), INTERNET_INVALID_PORT_NUMBER, _T ("test"), _T ("test"), INTERNET_SERVICE_FTP, 0, 1);
WaitForSingleObject (MayContinue, INFINITE);
HINTERNET Internet = (HINTERNET) LatestResult;
WIN32_FIND_DATA *FindData = new WIN32_FIND_DATA;
FtpFindFirstFileW (Internet, _T ("*.*"), FindData, 0, 1);
WaitForSingleObject (MayContinue, INFINITE);
delete FindData;
return 0;
}
What I've got after execution:
Unhandled exception at 0xBAADF00D in WinInetTest.exe:
0xC0000005: Access violation executing location 0xBAADF00D.
It happens somewhere around final WaitForSingleObject and callstack is rather confusing.
But if I change
WIN32_FIND_DATA *FindData = new WIN32_FIND_DATA;
FtpFindFirstFileW (Internet, _T ("*.*"), FindData, 0, 1);
to
WIN32_FIND_DATAA *FindData = new WIN32_FIND_DATAA;
FtpFindFirstFileA (Internet, "*.*", FindData, 0, 1);
It executes and works as it should.
So my question is - am I really not doing something correctly or it just failure on WinInet side?
I'm testing it on Windows 7 using Visual Studio 2012 btw.
I also had difficulty with FtpFindFirstFileW. When I converted my project from MBCS to Unicode FtpFindFirstFileW resulted in an access violation that appeared to be a pointer dereference of 0xbaadf00d somewhere after the call, possibly when the async result was being prepared. I worked around this by using FtpFindFirstFileA, InternetFindNextFileA and the WIN32_FIND_DATAA struct in both MBCS and Unicode builds. I then convert the output cFileName field to a TCHAR string.
I'd recommend changing compiler setting Character Set from Unicode to Multi-Byte Character Set. The same thing was happening to me.
i tried to extract all items from SysListView32,
this is the code:
#define WIN32_LEAN_AND_MEAN
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <commctrl.h>
int main(void) {
HWND hwnd=FindWindow(TEXT("Window"), TEXT("Cheat Engine 6.1"));
HWND win=FindWindowEx(hwnd, NULL, TEXT("Window"), NULL);
HWND listview=FindWindowEx(win, NULL, TEXT("SysListView32"), NULL);
int count=(int)SendMessage(listview, LVM_GETITEMCOUNT, 0, 0);
int i;
LVITEM lvi, *_lvi;
char item[512], subitem[512];
char *_item, *_subitem;
unsigned long pid;
HANDLE process;
GetWindowThreadProcessId(listview, &pid);
process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);
_lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
_item=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
_subitem=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
lvi.cchTextMax=512;
for(i=0; i<count; i++) {
lvi.iSubItem=0;
lvi.pszText=_item;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
lvi.iSubItem=1;
lvi.pszText=_subitem;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
ReadProcessMemory(process, _item, item, 512, NULL);
ReadProcessMemory(process, _subitem, subitem, 512, NULL);
printf("%s - %s\n", item, subitem);
}
VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
VirtualFreeEx(process, _item, 0, MEM_RELEASE);
VirtualFreeEx(process, _subitem, 0, MEM_RELEASE);
return 0;
}
Error:
cannot convert from 'char *' to 'LPWSTR' at line: lvi.pszText=_item;
Error 2:
IntelliSense: a value of type "char *" cannot be assigned to an entity of type "LPWSTR" at line: lvi.pszText=_subitem;
i tried TEXT(_subitem) , Still not working.
Use TCHAR* or wchar_t* instead of char*. Use TEXT() only for string literals.