EAccess violation with Processapi.cpp and Builder 5

c++ / delphi package - dll injection and api hooking
Post Reply
bparent
Posts: 7
Joined: Mon Mar 21, 2005 3:15 pm

EAccess violation with Processapi.cpp and Builder 5

Post by bparent »

I have successfully compiled and created an .exe using processapi.cpp and Builder 5 on WinXP professional with all patches. The program runs and displays the messagebox asking if it is ok to run notepad. When ok is clicked there is an EAcessViolation at addres 00000000. This occurs on this line:

return WinExecNextHook(lpCmdLine, uCmdShow);

I have tried declaring WinExecNextHook many different ways and without or without reference/pointers in the HookApi call. Everytime WinExecNextHook = NULL.

The only warnings given are:
[C++ Warning] processwinexec.cpp(53): W8030 Temporary used for parameter 'nextHook' in call to '__stdcall HookAPI(char *,char *,void *,void * &,unsigned int)'
[C++ Warning] processwinexec.cpp(59): W8030 Temporary used for parameter 'nextHook' in call to '__stdcall UnhookAPI(void * &)'

Any ideas on what is going on and how to correct this?

I saw a similar problem mentioned in the post regarding "unresolved external", but a solution was never posted.

Thanks.
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Can you please post the exact source code which you've compiled in BCB5? Thanks.
bparent
Posts: 7
Joined: Mon Mar 21, 2005 3:15 pm

Post by bparent »

This is the complete code:

/---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
USERES("processapimad.res");
//---------------------------------------------------------------------------

// ***************************************************************
// ProcessAPI version: 1.0 · date: 2003-06-15
// -------------------------------------------------------------
// simple demo to show process wide API hooking
// -------------------------------------------------------------
// Copyright (C) 1999 - 2003 www.madshi.net, All Rights Reserved
// ***************************************************************

// 2003-06-15 1.0 initial release

// ***************************************************************

#include <windows.h>
#include "madCodeHook.h"

// ***************************************************************

// variable for the "next hook", which we then call in the callback function
// it must have *exactly* the same parameters and calling convention as the
// original function
// besides, it's also the parameter that you need to undo the code hook again
UINT (WINAPI *WinExecNextHook)(LPCSTR lpCmdLine, UINT uCmdShow);

// this function is our hook callback function, which will receive
// all calls to the original SomeFunc function, as soon as we've hooked it
// the hook function must have *exactly* the same parameters and calling
// convention as the original function
UINT WINAPI WinExecHookProc(LPCSTR lpCmdLine, UINT uCmdShow)
{
// check the input parameters and ask whether the call should be executed
if (MessageBox(0, lpCmdLine, "Execute?", MB_YESNO | MB_ICONQUESTION) == IDYES)
// it shall be executed, so let's do it
return WinExecNextHook(lpCmdLine, uCmdShow);
else
// we don't execute the call, but we should at least return a valid value
return ERROR_ACCESS_DENIED;
}

// ***************************************************************

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// InitializeMadCHook is needed only if you're using the static madCHook.lib
InitializeMadCHook();

// we install our hook on the API...
// please note that in this demo the hook only effects our own process!
HookAPI("kernel32.dll", "WinExec", WinExecHookProc, (PVOID*) &WinExecNextHook,0);
// now call the original (but hooked) API
// as a result of the hook the user will receive our messageBox etc
WinExec("notepad.exe", SW_SHOWNORMAL);
// we like clean programming, don't we?
// so we cleanly unhook again
UnhookAPI((PVOID*) &WinExecNextHook);

// FinalizeMadCHook is needed only if you're using the static madCHook.lib
FinalizeMadCHook();

return true;
}

And, I have discovered with the following code I do not get any EAcessViollation and WinExecNextHook is also not null. But, notepad
still does not appear.

/---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
USERES("processapimad.res");
//---------------------------------------------------------------------------
#include <windows.h>
#include "madCodeHook.h"

// ***************************************************************

// variable for the "next hook", which we then call in the callback function
// it must have *exactly* the same parameters and calling convention as the
// original function
// besides, it's also the parameter that you need to undo the code hook again
UINT WINAPI WinExecNextHook(LPCSTR lpCmdLine, UINT uCmdShow)
{
//DO NOTHING
return((DWORD)0);
}
//WinExecNextHook = hookNext;
// this function is our hook callback function, which will receive
// all calls to the original SomeFunc function, as soon as we've hooked it
// the hook function must have *exactly* the same parameters and calling
// convention as the original function
UINT WINAPI WinExecHookProc(LPCSTR lpCmdLine, UINT uCmdShow)
{
// check the input parameters and ask whether the call should be executed
if (MessageBox(0, lpCmdLine, "Execute?", MB_YESNO | MB_ICONQUESTION) == IDYES)
// it shall be executed, so let's do it
return WinExecNextHook(lpCmdLine, uCmdShow);
else
// we don't execute the call, but we should at least return a valid value
return ERROR_ACCESS_DENIED;
}

// ***************************************************************

//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
// InitializeMadCHook is needed only if you're using the static madCHook.lib
//InitializeMadCHook();

// we install our hook on the API...
// please note that in this demo the hook only effects our own process!
HookAPI("kernel32.dll", "WinExec", (void *)WinExecHookProc, (void *) &WinExecNextHook,(unsigned int)0);
// now call the original (but hooked) API
// as a result of the hook the user will receive our messageBox etc
WinExec("notepad.exe", SW_SHOWNORMAL);
// we like clean programming, don't we?
// so we cleanly unhook again
UnhookAPI((PVOID*) &WinExecNextHook);

// FinalizeMadCHook is needed only if you're using the static madCHook.lib
//FinalizeMadCHook();

return true;

}
//---------------------------------------------------------------------------

Thanks, Bernie
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Just checked it with BCB. Don't ask me why, but BCB wants to have it like this:

Code: Select all

  HookAPI("kernel32.dll", "WinExec", WinExecHookProc, (PVOID) WinExecNextHook, 0);
  [...]
  UnhookAPI((PVOID) WinExecNextHook);
And I thought C++ would be somewhat compatible. <sigh>
bparent
Posts: 7
Joined: Mon Mar 21, 2005 3:15 pm

Post by bparent »

There must be something different in our code or configuration because when I changed the two lines of code as you suggested the API is not hooked. Notedpad shows but the message box is never displayed. I thought I had tried that combination before without success.

Are you including vcl.h ?
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

This one works fine for me:

Code: Select all

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
USERES("Project1.res");
//---------------------------------------------------------------------------
#include <windows.h>
#include "madCodeHook.h"

// ***************************************************************

// variable for the "next hook", which we then call in the callback function
// it must have *exactly* the same parameters and calling convention as the
// original function
// besides, it's also the parameter that you need to undo the code hook again
UINT (WINAPI *WinExecNextHook)(LPCSTR lpCmdLine, UINT uCmdShow);

// this function is our hook callback function, which will receive
// all calls to the original SomeFunc function, as soon as we've hooked it
// the hook function must have *exactly* the same parameters and calling
// convention as the original function
UINT WINAPI WinExecHookProc(LPCSTR lpCmdLine, UINT uCmdShow)
{
  // check the input parameters and ask whether the call should be executed
  if (MessageBox(0, lpCmdLine, "Execute?", MB_YESNO | MB_ICONQUESTION) == IDYES)
    // it shall be executed, so let's do it
    return WinExecNextHook(lpCmdLine, uCmdShow);
  else
    // we don't execute the call, but we should at least return a valid value
    return ERROR_ACCESS_DENIED;
}

// ***************************************************************

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
  // InitializeMadCHook is needed only if you're using the static madCHook.lib
  InitializeMadCHook();

  // we install our hook on the API...
  // please note that in this demo the hook only effects our own process!
  HookAPI("kernel32.dll", "WinExec", WinExecHookProc, (PVOID) WinExecNextHook, 0);
  // now call the original (but hooked) API
  // as a result of the hook the user will receive our messageBox etc
  WinExec("notepad.exe", SW_SHOWNORMAL);
  // we like clean programming, don't we?
  // so we cleanly unhook again
  UnhookAPI((PVOID) WinExecNextHook);

  // FinalizeMadCHook is needed only if you're using the static madCHook.lib
  FinalizeMadCHook();

  return true;
}
//---------------------------------------------------------------------------
bparent
Posts: 7
Joined: Mon Mar 21, 2005 3:15 pm

Post by bparent »

Thanks, that now works for me. Like you say, strange that C++ is different between VC and BCB. Now, off to try some of the system wide stuff with Builder.
Post Reply