Can't read export directory properly - c++

I'm trying to read export directory of a loaded module. The following program works as a 32-bit binary, but crashes as a 64-bit file.
All pointer is 64bit and I'm not sure the differences here, does anyone know what's wrong?
#include <windows.h>
#include <iostream>
#include <dbghelp.h>
#pragma comment(lib, "dbghelp.lib")
void PrintNames(HMODULE hModule)
{
DWORD dwExportsSize;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)ImageNtHeader(hModule);
PIMAGE_EXPORT_DIRECTORY ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(hModule, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &dwExportsSize);
PULONG Names = (PULONG)((DWORD)hModule + ExportDirectory->AddressOfNames);
for (ULONG cEntry = 0; cEntry < ExportDirectory->NumberOfNames; cEntry++)
{
printf("%s\n", (char*)((DWORD_PTR)hModule + Names[cEntry]));
}
}
int main()
{
PrintNames(GetModuleHandleA("ntdll"));
return 0;
}

A DWORD is 32 bit and not enough for 64 bit. Change it to DWORD_PTR if you need pointer size
PULONG Names = (PULONG)((DWORD_PTR)hModule + ExportDirectory->AddressOfNames);

Related

How to embed an exe file into another exe file as a resource in C++?

I am trying to use a pre-build .exe file as a resource in my C++ project, after searching I done the following steps:
Step1
Create a new C++ project and place the following code in the Source.cpp file
#include<iostream>
#include<Windows.h>
#include<fstream>
#define IDB_EMBEDEXE 52
using namespace std;
int main() {
int count = 2;
HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDB_EMBEDEXE), __TEXT("BINARY"));
HGLOBAL hGlobal = LoadResource(NULL, hResource);
size_t exeSiz = SizeofResource(NULL, hResource);
void* exeBuf = LockResource(hGlobal);
ofstream outfile((char*)exeBuf, ios::out | ios::binary);
if (!outfile)
exit(9);
outfile.write((char*)exeBuf, exeSiz);
system((char*)exeBuf);
return 0;
}
Step2 Create a new resource file (.rc)
1- Project>Add new item
2- From Installed>Visual C++>Resource choose Resource File (.rc) let us name it Resource.rc
Step3 Edit the header file resource.h that has just created from Step2, add the following line to the header file:
#define IDB_EMBEDEXE 52
Step4 Edit the Resource.rc file by right click on it>Open with>Source Code (Text) Editor, add the following code just after the first #include statment (i.e. after #include "resource.h"
#define IDB_EMBEDEXE 52
IDB_EMBEDEXE BINARY "C:\\Users\\Almohandis\\source\\repos\\Project7\\sum2num.exe"
After doing exactly these steps, I still get the following error in the cmd (not in the Visual Studio):
'MZ' is not recognized as an internal or external command,
operable program or batch file.
And the program ends with code 0
I think calling system() what causes the problem, especially the argument I passed.
Note that the binary representation of the sum2num.exe file starts with MZ....
If your #define is already in resource.h, there is no need to duplicate it in your source code. Just use #include "resource.h" in your code instead.
In any case, you should be using the pre-defined RCDATA resource type, instead of creating a custom BINARY type.
That being said, your use of ofstream and system() are both wrong. You are passing them the resource's raw binary data, but they are expecting a file path instead. You are using a file path in your .rc file to specify the file whose binary data is copied into the resource. The resource does not contain that file path, as you are clearly expecting.
Try this instead:
resource.h
...
#define IDB_EMBEDEXE 52
...
Resource.rc
#include "resource.h"
...
IDB_EMBEDEXE RCDATA "C:\\Users\\Almohandis\\source\\repos\\Project7\\sum2num.exe"
...
Source.cpp
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
#include "resource.h"
using namespace std;
int main() {
HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDB_EMBEDEXE), RT_RCDATA);
if (!hResource)
return 1;
HGLOBAL hGlobal = LoadResource(NULL, hResource);
if (!hGlobal)
return 2;
DWORD exeSiz = SizeofResource(NULL, hResource);
if (!exeSiz)
return 3;
void* exeBuf = LockResource(hGlobal);
if (!exeBuf)
return 4;
char tempPath[MAX_PATH] = {};
if (!GetTempPathA(MAX_PATH, path))
return 5;
string fullPath = string(tempPath) + "sum2num.exe";
ofstream outfile(fullPath.c_str(), ios::binary);
if (!outfile.is_open())
return 6;
int res = (outfile.write((char*)exeBuf, exeSiz)) ? 0 : 7;
outfile.close();
if (res == 0) {
system(fullPath.c_str());
}
remove(fullPath.c_str());
return res;
}

Why do IMFSourceReader::ReadSample block when I change the the camera output format?

I have the following Windows C++ code that I have adapted from:
https://alax.info/trac/public/browser/trunk/Utilities/MediaFoundation/VideoCaptureSynchronous/VideoCaptureSynchronous.cpp
More info about the original code:
https://alax.info/blog/1835
Thanks to Roman R!
#include <winsdkver.h>
#include <sdkddkver.h>
#include <stdio.h>
#include <tchar.h>
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#include <atlbase.h>
#include <atlcom.h>
#pragma comment(lib, "mfplat.lib")
#pragma comment(lib, "mf.lib")
#pragma comment(lib, "mfreadwrite.lib")
#define __C ATLENSURE_SUCCEEDED
#define __D ATLENSURE_THROW
static UINT32 g_nIndex = 1;
int main()
{
__C(MFStartup(MF_VERSION));
{
CComPtr<IMFMediaSource> pMediaSource;
{
CComPtr<IMFAttributes> pAttributes;
__C(MFCreateAttributes(&pAttributes, 1));
__C(pAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID));
CComHeapPtr<IMFActivate*> ppActivates;
UINT32 nActivateCount = 0;
__C(MFEnumDeviceSources(pAttributes, &ppActivates, &nActivateCount));
__D(g_nIndex < nActivateCount, E_INVALIDARG);
const CComPtr<IMFActivate> pActivate = ppActivates[g_nIndex];
for (UINT32 nIndex = 0; nIndex < nActivateCount; nIndex++)
reinterpret_cast<CComPtr<IMFActivate>&>(ppActivates[nIndex]).Release();
__C(pActivate->ActivateObject(__uuidof(IMFMediaSource), (VOID**)&pMediaSource));
CComHeapPtr<WCHAR> pszFriendlyName;
__C(pActivate->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &pszFriendlyName, NULL));
_tprintf(_T("Friendly Name: %ls\n"), (LPCWSTR)pszFriendlyName);
}
CComPtr<IMFSourceReader> pSourceReader;
__C(MFCreateSourceReaderFromMediaSource(pMediaSource, NULL, &pSourceReader));
// Start My code
CComPtr<IMFMediaType> mediaType;
int index = 4;
__C(pSourceReader->GetNativeMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, index, &mediaType)); // returns MF_E_NO_MORE_TYPES if index is too large
__C(pSourceReader->SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, mediaType));
// End my code
LONGLONG nBaseTime = 0;
for (; ; )
{
DWORD nStreamIndex;
DWORD nStreamFlags;
LONGLONG nTime;
CComPtr<IMFSample> pSample;
__C(pSourceReader->ReadSample(MF_SOURCE_READER_ANY_STREAM, 0, &nStreamIndex, &nStreamFlags, &nTime, &pSample));
nTime -= nBaseTime;
_tprintf(_T("nStreamIndex %d, nStreamFlags 0x%X, nTime %.3f, pSample 0x%p\n"), nStreamIndex, nStreamFlags, nTime / 1E7, (IMFSample*)pSample);
if (nStreamIndex == 0 && (nStreamFlags & MF_SOURCE_READERF_STREAMTICK))
{
ATLASSERT(!pSample);
nBaseTime = nTime;
continue;
}
}
}
__C(MFShutdown());
return 0;
}
My changes are within the Start my code/End my code block.
Without my changes the code runs fine.
With my changes however I only get one NULL sample from ReadSample() and after that it blocks
in ReadSample().
The output is:
Friendly Name: M034-WDR
nStreamIndex 0, nStreamFlags 0x100, nTime 65175.109, pSample 0x0000000000000000
I have listed the IMFMediaTypes supported by the camera with some other code and found that it had 8 different native formats out of which I preferred number 4.
How can I select this format and get this code to run?
I tried changing to
ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM,..)
but that did not help.

The LPCSTR type string is garbled or displayed error

I have a LPCSTR that I want to convert to std::string or char*.
LPCSTR strName;
_tprintf(_T("%s\n"), strName);
I'm trying to get all the audio equipment on the computer and displayed, but to get the LPCSTR type of direct output is garbled, use the above code to output the correct results.
Is there a way to save the correct output?
The following is the complete code:
Add a dependency to the property:
comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;odbc32.lib;odbccp32.lib
ListSoundDev.h
#ifndef _LISTSOUNDDEV_HEAD_
#define _LISTSOUNDDEV_HEAD_
#include<tchar.h>
#include <dshow.h>
#include<iostream>
#include<vector>
#include<mmsystem.h>
#include<mmreg.h>
#include<dsound.h>
#pragma comment(lib, "strmiids.lib")
#pragma comment(lib, "Quartz.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "dsound.lib")
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "strmiids")
using namespace std;
typedef struct _DevItem
{
LPCSTR strName;
GUID guid;
} DevItem;
#endif
main.cpp
#include"ListSoundDev_head.h"
std::vector<DevItem> m_CapDevices;
BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext)
{
std::vector<DevItem> *pLst = (std::vector<DevItem> *) lpContext;
if (pLst)
{
DevItem item;
memset(&item, 0, sizeof(item));
item.strName = lpcstrDescription;
if (lpGuid)
item.guid = *lpGuid;
else
item.guid = GUID_NULL;
pLst->push_back(item);
return TRUE;
}
return FALSE;
}
int main()
{
std::vector<DevItem>::iterator it;
HRESULT hr = S_OK;
setlocale(LC_ALL, "chs");
hr = DirectSoundCaptureEnumerate((LPDSENUMCALLBACKW)DSEnumCallback, (LPVOID)&m_CapDevices);
for (it = m_CapDevices.begin(); it != m_CapDevices.end(); it++){
_tprintf(_T("%s\n"), it->strName);//output correct
printf("%s\n",it->strName);//output error
std::cout << it->strName << std::endl;//output error
}
}
Expected output:
麦克风 (Realtek High Definition Au
Actual output:
KQ螛
Expected output:
Realtek Digital Input (Realtek
Actual output:
R
How can I that printf() or std::cout can directly output the correct results?
Thank you very much for your answer, I have solved this problem.
The solution is to use the following code to convert.
The character set is Unicode.
char newStr[100];
wcstombs(newStr, (wchar_t*)it->strName, 100);
printf("newStr=%s\n", newStr);
The character set is Multibyte
printf("%s\n", it->strName);
However, when I write this program in the C + + console to obtain the name of the audio device for the microphone (Realtek High Definition Au, but in MFC using this code to get the device name for the microphone (Realtek High Definition Audio) What is the reason?

NetUserChangePassword C++

I would like to change user password on my Windows 7 PC using C++.
But when I compile it gets error:
undefined reference to 'NetUserChangePassword'
[Error] ld returned 1 exit status.`
How can I fix it?
Here is the MSDN page with the NetUserChangePassword function:
#ifndef UNICODE
#define UNICODE
#endif
#pragma comment(lib, "netapi32.lib")
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <lm.h>
bool ChangeUserPassword(LPCWSTR OldPassword, LPCWSTR NewPassword)
{
NET_API_STATUS nStatus;
LPTSTR lp = new TCHAR[256];
DWORD dw = 256;
GetUserName(lp, &dw);
nStatus = NetUserChangePassword(NULL, lp, OldPassword, NewPassword);
delete[] lp;
if (nStatus == NERR_Success)
return true;
return false;
}
int main(int argc, char** argv)
{
LPCWSTR Old_P = L"C";
LPCWSTR New_P = L"D";
ChangeUserPassword(Old_P, New_P);
return 0;
}
I tried to link to the project the winapi32.dll in two ways
i tried to add using the project option
i tried to add following line
HINSTANCE hInst = LoadLibrary( L"C:\\Windows\\System32\\netapi32.dll ");
but i get always the same error
The requirements section of the MSDN topic you linked to states that you must link the Netapi32.lib library. That is the step that you have missed and explains the missing external error.
As to how to resolve the problem it is hard to say for sure. You are not using the MS compiler and so the #pragma approach won't work. Consult the docs for your compiler/linker to work out how to link this library.
It looks like you are using a GCC based compiler and so need to add -lnetapi32 to the options.

Linking failure. How to use 'NtQuerySystemTime' windows function?

I try this simple code to calculate HDD write speed in my application:
#include <winternl.h>
...
float speed;
double divident;
PLARGE_INTEGER systime0, systime1;
LONGLONG elapsed_time;
...
write_flag = true ;
NtQuerySystemTime(systime0) ;
f_out->write(out_buffer0, chunk_len0);
f_out->write(out_buffer1, chunk_len1);
NtQuerySystemTime(systime1);
elapsed_time = systime1->QuadPart - systime0->QuadPart;
write_flag = false ;
divident = static_cast<double>(chunk_len0 + chunk_len1) / 1.048576 ; // 1.024 * 1.024 = 1.048576; divident yield value 1000000 times greater then value in MB
divident *= 10 ; // I want 'speed' to be in MB/s
speed = divident / static_cast<double>(elapsed_time) ;
...
but it fails to link.
On MSDN, the NtQuerySystemTime documentation says there is no associated import library and that I must use the LoadLibrary() and GetProcAddress() functions to dynamically link to Ntdll.dll. But I don't understand how to use those functions. Can someone please provide a code example of how to use those functions?
This is how you would be able to use this function.
HMODULE hNtDll = GetModuleHandleA("ntdll");
NTSTATUS (WINAPI *NtQuerySystemTime)(PLARGE_INTEGER) =
(NTSTATUS (WINAPI*)(PLARGE_INTEGER))GetProcAddress(hNtDll, "NtQuerySystemTime");
#include <stdio.h>
#include <windows.h>
typedef NTSYSAPI (CALLBACK *LPNTQUERYSYSTEMTIME)(PLARGE_INTEGER);
void main(void)
{
PLARGE_INTEGER SystemTime;
SystemTime = (PLARGE_INTEGER) malloc(sizeof(LARGE_INTEGER));
HMODULE hNtDll = GetModuleHandleA("ntdll");
LPNTQUERYSYSTEMTIME fnNtQuerySystemTime = (LPNTQUERYSYSTEMTIME)GetProcAddress(hNtDll, "NtQuerySystemTime");
if(fnNtQuerySystemTime){
printf("found NtQuerySystemTime function at ntdll.dll address:%p\n",fnNtQuerySystemTime);
fnNtQuerySystemTime(SystemTime);
printf("%llx\n", SystemTime->QuadPart);
}
free(SystemTime);
}