|
What have you done so far ? Watched code never compiles.
|
|
|
|
|
zakria81 wrote: I know it a long question
I can't see any question.
|
|
|
|
|
Hi,
My purpose is to help the author of mpatrol to make that program as easy to use than valgrind on Windows. So i tried to look at DLL injection and API hooking.
I have written a program (named valgrind :p) and a DLL to test those 2 technics. More precisely, I have:
- valgrind.exe : the program that will inject the DLL below
- valgrind.dll : the DLL that will be injected in an executable and that will do API hooking
- valgrind_test.exe : a executable that calls a function overloaded in valgrind.dll
I have taken some bits of code here and there in CodeProject. For the DLL injection, I used the VirtualAllocEx() / CreateRemoteThread() technic. For the API hooking, I enumerate all the modules and use ImageDirectoryEntryToData().
Here are the different codes:
valgrind.c
#include <stdio.h>
#include <string.h>
#include <windows.h>
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_SUSPEND_RESUME | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
typedef HMODULE (*_load_library) (const char *);
typedef BOOL (*_free_library) (HMODULE);
typedef struct _Vg Vg;
struct _Vg
{
_load_library ll;
_free_library fl;
char *dll_fullname;
int dll_length;
struct {
HANDLE process1;
HANDLE thread;
HANDLE process2;
} child;
DWORD exit_code;
};
FARPROC
_vg_symbol_get (const char *module, const char *symbol)
{
HMODULE mod;
FARPROC proc;
printf (" * loading library %s... ", module);
mod = LoadLibrary(module);
if (!mod)
{
printf("failed\n", module);
return NULL;
}
printf ("done\n");
printf (" * retrieving symbol %s... ", symbol);
proc = GetProcAddress(mod, symbol);
if (!proc)
{
printf("failed\n", symbol);
goto free_library;
}
printf ("done\n");
FreeLibrary(mod);
return proc;
free_library:
FreeLibrary(mod);
return NULL;
}
Vg *
vg_new()
{
char buf[MAX_PATH];
Vg *vg;
HMODULE kernel32;
DWORD length;
kernel32 = LoadLibrary("kernel32.dll");
if (!kernel32)
{
printf("no kernel32.dll found\n");
return 0;
}
if (!GetProcAddress(kernel32, "CreateRemoteThread"))
{
printf("no CreateRemoteThread found\n");
goto free_kernel32;
}
vg = (Vg *)calloc (1, sizeof (Vg));
if (!vg)
goto free_kernel32;
vg->ll = (_load_library)_vg_symbol_get("kernel32.dll", "LoadLibraryA");
if (!vg->ll)
goto free_vg;
vg->fl = (_free_library)_vg_symbol_get("kernel32.dll", "FreeLibrary");
if (!vg->fl)
goto free_vg;
length = GetFullPathName("valgrind_dll.dll", MAX_PATH, buf, NULL);
if (!length)
{
printf ("can't get full path name\n");
goto free_vg;
}
vg->dll_fullname = _strdup(buf);
if (!vg->dll_fullname)
goto free_vg;
vg->dll_length = length + 1;
FreeLibrary(kernel32);
return vg;
free_vg:
free(vg);
free_kernel32:
FreeLibrary(kernel32);
return 0;
}
void
vg_del(Vg *vg)
{
if (!vg)
return;
if (vg->child.process2)
CloseHandle(vg->child.process2);
if (vg->child.thread)
CloseHandle(vg->child.thread);
if (vg->child.process1)
CloseHandle(vg->child.process1);
free(vg->dll_fullname);
free(vg);
}
int vg_dll_inject(Vg *vg, const char *prog)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE process;
HANDLE remote_thread;
LPVOID remote_string;
DWORD exit_code;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
printf (" * creating child process %s... ", prog);
if (!CreateProcess(NULL, (char *)prog, NULL, NULL, TRUE,
CREATE_SUSPENDED, NULL, NULL, &si, &pi))
{
printf ("failed\n * can't spawn child process %s\n", prog);
return 0;
}
printf ("done\n");
printf (" * waiting for the child process to initialize... ");
if (!WaitForInputIdle(pi.hProcess, INFINITE))
{
printf("failed\n * no process for %s\n", prog);
goto close_handles;
}
printf ("done\n");
printf (" * opening child process... ");
process = OpenProcess(CREATE_THREAD_ACCESS, FALSE, pi.dwProcessId);
if (!process)
{
printf("failed\n * no process for %s\n", prog);
goto close_handles;
}
printf ("done\n");
printf (" * allocating virtual memory... ");
remote_string = VirtualAllocEx(process, NULL, vg->dll_length, MEM_COMMIT, PAGE_READWRITE);
if (!remote_string)
{
printf("failed\n");
goto close_process;
}
printf ("done\n");
printf(" * writing process in virtual memory... ");
if (!WriteProcessMemory(process, remote_string, vg->dll_fullname, vg->dll_length, NULL))
{
printf("failed\n");
goto virtual_free;
}
printf ("done\n");
printf (" * execute thread... ");
remote_thread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)vg->ll, remote_string, 0, NULL);
if (!remote_thread)
{
printf("failed\n");
goto virtual_free;
}
printf ("done\n");
WaitForSingleObject(remote_thread, INFINITE);
printf (" * getting exit code... ");
if (!GetExitCodeThread(remote_thread, &exit_code))
{
printf("failed\n");
goto close_thread;
}
printf ("done\n");
CloseHandle(remote_thread);
VirtualFreeEx(process, remote_string, vg->dll_length + 1, MEM_RELEASE);
printf(" * resume child process\n");
ResumeThread(pi.hThread);
vg->child.process1 = pi.hProcess;
vg->child.thread = pi.hThread;
vg->child.process2 = process;
vg->exit_code = exit_code;
return 1;
close_thread:
CloseHandle(remote_thread);
virtual_free:
VirtualFreeEx(process, remote_string, vg->dll_length, MEM_RELEASE);
close_process:
CloseHandle(process);
close_handles:
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}
void
vg_dll_extract(Vg *vg)
{
HANDLE thread;
thread = CreateRemoteThread(vg->child.process2, NULL, 0,
(LPTHREAD_START_ROUTINE)vg->fl,
(void*)vg->exit_code, 0, NULL );
WaitForSingleObject(thread, INFINITE );
CloseHandle(thread );
}
int main(int argc, char *argv[])
{
Vg *vg;
vg = vg_new();
if (!vg)
return -1;
if (!vg_dll_inject(vg, "valgrind_test.exe"))
{
printf(" * injection failed\n * exiting...\n");
goto del_vg;
}
Sleep(2000);
printf(" * fin process\n");
vg_dll_extract(vg);
vg_del(vg);
printf(" * ressources freed\n");
return 0;
del_vg:
vg_del(vg);
return -1;
}
valgrind.dll
#include <stdio.h>
#include <windows.h>
#include <psapi.h>
#include <imagehlp.h>
typedef struct
{
char *func_name_old;
PROC func_proc_old;
PROC func_proc_new;
} Vg_Hook;
typedef LPVOID (WINAPI *vgd_heap_alloc_t) (HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
typedef BOOL (WINAPI *vgd_heap_free_t) (HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
typedef void (WINAPI *vgd_get_system_info_t)(LPSYSTEM_INFO lpSystemInfo);
typedef void (WINAPI *vgd_get_system_time_t)(LPSYSTEM_INFO lpSystemTime);
Vg_Hook vg_hooks_kernel32[2];
LPVOID WINAPI VG_HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
{
vgd_heap_alloc_t *ha;
LPVOID data;
printf("HeapAlloc !!!\n");
ha = (vgd_heap_alloc_t *)vg_hooks_kernel32[0].func_proc_old;
data = (*ha)(hHeap, dwFlags, dwBytes);
return data;
}
BOOL WINAPI VG_HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
{
vgd_heap_free_t *hf;
BOOL res;
printf("HeapFree !!!\n");
hf = (vgd_heap_free_t *)vg_hooks_kernel32[1].func_proc_old;
res = (*hf)(hHeap, dwFlags, lpMem);
return res;
}
void WINAPI VG_GetSystemInfo(LPSYSTEM_INFO lpSystemInfo)
{
vgd_get_system_info_t *gsi;
printf ("GetSystemInfo !!!\n");
gsi = (vgd_get_system_info_t *)vg_hooks_kernel32[0].func_proc_old;
(*gsi)(lpSystemInfo);
}
void WINAPI VG_GetSystemTime(LPSYSTEM_INFO lpSystemTime)
{
vgd_get_system_time_t *gst;
printf ("GetSystemTime !!!\n");
gst = (vgd_get_system_time_t *)vg_hooks_kernel32[1].func_proc_old;
(*gst)(lpSystemTime);
}
#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr)+(DWORD)(addValue))
void
_vgd_modules_hook_set(HMODULE module, const char *lib_name, PROC old_function_proc, PROC new_function_proc)
{
PIMAGE_IMPORT_DESCRIPTOR iid;
PIMAGE_THUNK_DATA thunk;
ULONG size;
iid = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(module, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size);
if (!iid)
return;
while (iid->Name)
{
PSTR module_name;
module_name = (PSTR)((PBYTE) module + iid->Name);
if (_stricmp(module_name, lib_name) == 0)
break;
iid++;
}
if (!iid->Name)
return;
thunk = (PIMAGE_THUNK_DATA)((PBYTE)module + iid->FirstThunk );
while (thunk->u1.Function)
{
PROC *func;
func = (PROC *)&thunk->u1.Function;
if (*func == old_function_proc)
{
MEMORY_BASIC_INFORMATION mbi;
DWORD dwOldProtect;
VirtualQuery(func, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
if (!VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &mbi.Protect))
return;
*func = *new_function_proc;
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, &dwOldProtect);
break;
}
thunk++;
}
}
void
_vgd_modules_hook(HMODULE main_module, const char *lib_name)
{
HMODULE mods[1024];
HMODULE lib_module;
DWORD mods_nbr;
unsigned int i;
unsigned int j;
lib_module = LoadLibrary(lib_name);
for (j = 0; vg_hooks_kernel32[j].func_name_old; j++)
vg_hooks_kernel32[j].func_proc_old = GetProcAddress(lib_module, vg_hooks_kernel32[j].func_name_old);
if (!EnumProcessModules(GetCurrentProcess(), mods, sizeof(mods), &mods_nbr))
return;
for (i = 0; i < (mods_nbr / sizeof(HMODULE)); i++)
{
if (mods[i] == main_module)
continue;
for (j = 0; vg_hooks_kernel32[j].func_name_old; j++)
_vgd_modules_hook_set(mods[i], lib_name,
vg_hooks_kernel32[j].func_proc_old,
vg_hooks_kernel32[j].func_proc_new);
}
FreeLibrary(lib_module);
}
void
_vgd_modules_unhook(HMODULE main_module, const char *lib_name)
{
HMODULE mods[1024];
DWORD mods_nbr;
unsigned int i;
unsigned int j;
if (!EnumProcessModules(GetCurrentProcess(), mods, sizeof(mods), &mods_nbr))
return;
for (i = 0; i < (mods_nbr / sizeof(HMODULE)); i++)
{
if (mods[i] == main_module) continue;
for (j = 0; vg_hooks_kernel32[j].func_name_old; j++)
_vgd_modules_hook_set(mods[i], lib_name,
vg_hooks_kernel32[j].func_proc_new,
vg_hooks_kernel32[j].func_proc_old);
}
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ulReason, LPVOID lpReserved)
{
vg_hooks_kernel32[0].func_name_old = "GetSystemInfo";
vg_hooks_kernel32[0].func_proc_old = NULL;
vg_hooks_kernel32[0].func_proc_new = (PROC)VG_GetSystemInfo;
vg_hooks_kernel32[1].func_name_old = "GetSystemTime";
vg_hooks_kernel32[1].func_proc_old = NULL;
vg_hooks_kernel32[1].func_proc_new = (PROC)VG_GetSystemTime;
vg_hooks_kernel32[2].func_name_old = NULL;
vg_hooks_kernel32[2].func_proc_old = NULL;
vg_hooks_kernel32[2].func_proc_new = NULL;
switch (ulReason)
{
case DLL_PROCESS_ATTACH:
printf ("DLL attach\n");
printf ("hooking... ");
_vgd_modules_hook(hModule, "kernel32.dll");
printf ("finished\n");
break;
case DLL_PROCESS_DETACH:
printf ("DLL detach\n");
break;
}
return TRUE;
}
and the test code :
#include <stdio.h>
#include <windows.h>
int main()
{
SYSTEMTIME st;
GetSystemTime(&st);
return 0;
}
Now, the problems:
- If i don't hook the functions in valgrind.dll, the injection is correctly done (there is a message displayed when the DLLL process is attached and one when the test example is executed).
- If I hook several functions, the test program is executed, but an exception is raised (see the comment at the bottom of the test file. Sorry it is in french...)
I don't understand at all the problem.
Here is an archive of the code (with a Makefile for the gcc users or a visual studio solution) to test the code)
Does someone see the problem ?
thank you
|
|
|
|
|
Hi
I have a MDI application. I added functions for "ID_FILE_SAVE" and "ID_FILE_SAVE_AS". But When I ran the application and tried the "Save" and "Save As" menu, application will never go to the defined function. There is always "File Save as" dialog box show.
How can I catch the "ID_FILE_SAVE"? How can I know where the application goes?
Thanks,
|
|
|
|
|
What do the message map entries for ID_FILE_SAVE and ID_FILE_SAVE_AS look like?"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
I used class property to add "message map entries". But software does not go there. I think I messed up something.
Thanks,
|
|
|
|
|
It works perfectly for me.
I added the event handler called OnFileSave in the view class.
You probably added the event handler in the wrong class that is not part of the doc-view architecture.
|
|
|
|
|
Yes, It works perfectly for other application.
BEGIN_MESSAGE_MAP( CSplitFrame, CMDIChildWnd )
ON_COMMAND( ID_FILE_SAVE, IDFileSave )
ON_COMMAND( ID_FILE_SAVE_AS, IDFileSaveAs )
...
Is there a way to catch the message?modified on Monday, February 15, 2010 10:14 AM
|
|
|
|
|
The problem lies in the class in which you're trying to put a handler for it.
In an MDI application it is the View class that gets the first chance to handle the message.
If there is no handler, the control goes to the document class.
Only then does the child frame get a chance to handle the message.
What you're seeing is the default implementation of the document class.
You can catch the message by adding the handler in the view class or the document class.
|
|
|
|
|
Hi friends
How to compact a database using CDatabase class or any other method in Visual C++
thanks in advance-kk.tvm-
|
|
|
|
|
See, for instance, from the competitors : "Compact an Access Database Programmatically".
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Hi, The OutlookDemo Sample of MFC new Feature pack implements a very good style of CMFCOutlookBarTabCtrl class that when you configure the gui to look in office 2003 and office XP modes the tabs of the CMFCOutlookbar Open and go upward by clicking on them but I couldn't found what to do reach this style of tabs through the sample source code. if any one knows the answer I will be thankful if he could modify my below code so i could reach that style.
m_wndOutlookBar.SetMode2003(true);
m_wndOutlookBar.Create(_T("test"), this, CRect (50, 50, 500, 500), ID_VIEW_OUTLOOKBAR, WS_CHILD | WS_VISIBLE | CBRS_LEFT);
m_wndOutlookPane1.Create (&m_wndOutlookBar,
AFX_DEFAULT_TOOLBAR_STYLE, ID_OUTLOOK_PANE_GENERAL, AFX_CBRS_FLOAT | AFX_CBRS_RESIZE);
m_wndOutlookPane1.EnableDocking (CBRS_ALIGN_ANY);
m_wndOutlookPane1.AddButton (theApp.LoadIcon (IDR_MAINFRAME), L"Open", ID_APP_ABOUT);
m_wndOutlookPane2.Create (&m_wndOutlookBar,
AFX_DEFAULT_TOOLBAR_STYLE, ID_OUTLOOK_PANE_SPECIAL, AFX_CBRS_FLOAT | AFX_CBRS_RESIZE);
m_wndOutlookPane2.EnableDocking (CBRS_ALIGN_ANY);
CMFCOutlookBarTabCtrl::EnableAnimation(TRUE);
CMFCOutlookBarTabCtrl* pOutlookBar =
(CMFCOutlookBarTabCtrl*) m_wndOutlookBar.GetUnderlyingWindow ();
pOutlookBar->EnableInPlaceEdit(TRUE);
pOutlookBar->EnableAnimation(true);
pOutlookBar->EnableScrollButtons();
pOutlookBar->EnableTabSwap(true);
(CMFCBaseTabCtrl*)pOutlookBar->EnableTabDetach(0,true);
pOutlookBar->AddTab (&m_wndOutlookPane1, L"General", (UINT) -1, TRUE);
pOutlookBar->AddTab (&m_wndOutlookPane2, L"Special", (UINT) -1, TRUE);
|
|
|
|
|
I Found Answer By my self ,And It was about the method
m_wndBarOutlook.SetMode2003(TRUE);
Because in the sample program of MSDN in the 2003 style and XP Mode it changes the way I like I never think of that to have this style
I should use it the following way
m_wndBarOutlook.SetMode2003(FALSE);
|
|
|
|
|
I run a worker thread like this:
m_first = AfxBeginThread(MyThreadProcTT1, segmentation,THREAD_PRIORITY_ABOVE_NORMAL);
in the MyThreadProcTT1, i run four worker threads like this:
CWinThread* first=NULL;
first = AfxBeginThread(MyThreadProc, pNewObject,THREAD_PRIORITY_ABOVE_NORMAL);
second = AfxBeginThread(MyThreadProc1, pNewObject1,THREAD_PRIORITY_ABOVE_NORMAL);
third = AfxBeginThread(MyThreadProc2, pNewObject2,THREAD_PRIORITY_ABOVE_NORMAL);
forth = AfxBeginThread(MyThreadProc3, pNewObject3,THREAD_PRIORITY_ABOVE_NORMAL);
WaitForSingleObject(first->m_hThread, INFINITE);
WaitForSingleObject(second->m_hThread, INFINITE);
WaitForSingleObject(third->m_hThread, INFINITE);
WaitForSingleObject(forth->m_hThread, INFINITE);
in most of the time, the program work fine. But in some situations, the program halts and do not anything!
Is there anyone can help me!
Best,
MJM
|
|
|
|
|
I spot an issue in your code: All threads have their priorities set to THREAD_PRIORITY_ABOVE_NORMAL , which I think could be avoided. What is your justification for doing this?
mostafa_pasha wrote: But in some situations, the program halts and do not anything!
And what does that mean? Have you used the debugger to step into the code? Have you verified all the WaitForSingleObject calls have returned (as you're asking the program to wait for an INFINITE amount of time)?!
“Follow your bliss.” – Joseph Campbell
|
|
|
|
|
I taught coping the software is for thread priority.So i tried to change the priority to ABOVE_NORMAL.
About debugging,
i changed the code:
WinThread* first=NULL;
first = AfxBeginThread(MyThreadProcT, &pmom1,THREAD_PRIORITY_ABOVE_NORMAL);
if(first == NULL)
{
AfxMessageBox(_T("Can not run a thread!!!"));
return;
}
CWinThread* second=NULL;
second = AfxBeginThread(MyThreadProcT1, &pmom2,THREAD_PRIORITY_ABOVE_NORMAL);
if(second == NULL)
{
AfxMessageBox(_T("Can not run a thread!!!"));
return;
}
if (WaitForSingleObject(first->m_hThread, INFINITE) == WAIT_FAILED)
{
ErrorExit(TEXT("Thread_First")); // show the GetLastError
}
if (WaitForSingleObject(second->m_hThread, INFINITE))
{
ErrorExit(TEXT("Thread_Second")); // show the GetLastError
}
I caught this message box:
Thread_Second failed with error 6: The Handle is invalid!!!
Does it mean second thread finish before the the first thread?
Best
MJM
|
|
|
|
|
mostafa_pasha wrote: Thread_Second failed with error 6: The Handle is invalid!!!
It could mean that the thread was not even started. Remember that these operations are completely asynchronous. The code has reached the WFSO call does not mean the thread creation function called above that has successfully spawned the thread by then.
I'd strongly recommend that you get your basics right. Read this essay by Dr. Joseph Newcomer, which covers many aspects: Worker Threads[^]
“Follow your bliss.” – Joseph Campbell
|
|
|
|
|
Unfortunately, I used SetEvent , .... in the debug mode, everything is OK.
in the release mode, it seems that the threads can not start!!!
Best,
MJM
|
|
|
|
|
mostafa_pasha wrote: Unfortunately, I used SetEvent , .... in the debug mode, everything is OK.
in the release mode, it seems that the threads can not start!!!
Please read this: Debug vs Release[^]
“Follow your bliss.” – Joseph Campbell
|
|
|
|
|
Language: Visual C++ 6.0; MFC app with CWinApp-based class
OS: WinXP
I use a COM component (http://www.emailarchitect.net/webapp/popcom/) in MFC app. I release it BEFORE call of ExitInstance; in ExitInstance I call CoUninitialize. This CoUninitialize hangs. If I call CoUninitialize not from ExitInstance but right after the COM object is released - no hangs.
All I know about this COM component is it uses asyncronous mode amd uses sink interfaces for client notification. Partially it uses ATL's method DispEventAdvise. My application has not its own cycles of message processing - only standard MFC cycle in CWinApp.
The hang does not depend on what was used to initialize COM: CoInitialize( NULL ) or CoInitializeEx(NULL, COINIT_APARTMENTTHREADED).
|
|
|
|
|
Please check the return value of your CoInitialize call, I suspect you hit this [^].
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
I did it; it returns S_OK. Ni more calls of CoInitialize* in teh program
|
|
|
|
|
I need to display a huge size file(1GB) content in a dialog, when it is popup to the user. I tried to read the file content in oninitdialog(), but since huge size, dialog takes some more time to display. Is there any other way to read and display the file content with minimum time?
Kindly help me asap!
|
|
|
|
|
You can use overlapped or asynchronous read operations on the file.
This way you can initiate the read from OnInitDialog where the read function will immediately return and complete later.
Read about it here - Synchronous and Asynchronous I/O[^]
|
|
|
|
|
Thanks a lot Superman. But Is it possible to do it in any other function excluding oninitdialog()? This is just my doubt.
|
|
|
|
|