HookCode IFileDialog::GetResult problem HELP ME !!

c++ / delphi package - dll injection and api hooking

HookCode IFileDialog::GetResult problem HELP ME !!

Postby DohyunShin » Thu Oct 27, 2016 1:13 am

I hooked GetResult method to get the dialog's result. (The dialog is created by IFileOpenDialog.- COM Object)

First, I hooked CoCreateInstance using HookAPI and got the address of IFileOpenDialog.
Then, I hooked GetResult method using HookCode.

My source code is shown below.
Code: Select all
PVOID GetInterfaceMethod64(PVOID intf, DWORD methodIndex)
{
   return *(PVOID*)(*(ULONG_PTR*)intf + methodIndex * sizeof(PVOID));
}
PVOID GetInterfaceMethod(PVOID intf, DWORD methodIndex)
{
   return *(PVOID*)(*(DWORD*)intf + methodIndex * 4);
}

// ~Next method definitions
HRESULT(WINAPI *GetResultNext)(IFileOpenDialog * This, IShellItem **ppsi);
HRESULT(WINAPI *GetResultsNext)(IFileOpenDialog * This, IShellItemArray **ppenum);
HRESULT(WINAPI *CoCreateInstanceNext)(REFCLSID  rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv);

// ~Callback method definitions
HRESULT WINAPI GetResultCallback(IFileOpenDialog * This, IShellItem **ppsi)
{
   HRESULT hrResult = GetResultNext(This, ppsi);
   if (!SUCCEEDED(hrResult)) return hrResult;

   DWORD dwPid = GetCurrentProcessId();
   GetResultDataHandle(ppsi, dwPid);

   OutputDebugString(_T("IFileDialog::GetResult End"));
   return hrResult;
}
HRESULT WINAPI GetResultsCallback(IFileOpenDialog * This, IShellItemArray **ppenum)
{
   HRESULT hrResult = GetResultsNext(This, ppenum);
   if (!SUCCEEDED(hrResult)) return hrResult;

   DWORD dwPid = GetCurrentProcessId();
   GetResultsDataHandle(ppenum, dwPid);

   OutputDebugString(_T("IFileOpenDialog::GetResults End"));
   return hrResult;
}
HRESULT WINAPI CoCreateInstanceCallback(
   REFCLSID  rclsid,
   LPUNKNOWN pUnkOuter,
   DWORD     dwClsContext,
   REFIID    riid,
   LPVOID    *ppv
) {
   HRESULT hrResult = CoCreateInstanceNext(rclsid, pUnkOuter, dwClsContext, riid, ppv);
   
   if (hrResult == S_OK && rclsid == CLSID_FileOpenDialog) {
      LPVOID pGetResult;
      LPVOID pGetResults;
#ifdef WIN64
      OutputDebugString(_T("[hookofficepro] CoCreateInstance Callback Info : WIN64"));
      pGetResult = GetInterfaceMethod64(*ppv, 20);
      pGetResults = GetInterfaceMethod64(*ppv, 27);
#else
      OutputDebugString(_T("[hookofficepro] CoCreateInstance Callback Info : WIN32"));
      pGetResult = GetInterfaceMethod(*ppv, 20);
      pGetResults = GetInterfaceMethod(*ppv, 27);
#endif
      if (!GetResultNext) {
         if (!HookCode(pGetResult, GetResultCallback, (PVOID *)&GetResultNext))
            OutputDebugString(_T("IFileDilaog::GetResult Hook Fail"));
         else
            OutputDebugString(_T("IFileDilaog::GetResult Hook Success"));
      }
      else
         RenewHook((PVOID*)&GetResultNext);
         

      if (!GetResultsNext) {
         if (!HookCode(pGetResults, GetResultsCallback, (PVOID *)&GetResultsNext))
            OutputDebugString(_T("IFileOpenDilaog::GetResults Hook Fail"));
         else
            OutputDebugString(_T("IFileOpenDilaog::GetResults Hook Success"));
      }
      else
         RenewHook((PVOID*)&GetResultsNext);
   }
   return hrResult;
}

// Hook Install & Uninstall
BOOL InstallAPIHook()
{
   HookAPI("Ole32.dll", "CoCreateInstance", CoCreateInstanceCallback, (PVOID*)&CoCreateInstanceNext)
   return TRUE;
}

void UninstallAPIHook() {
   UninstallHookCode(&CoCreateInstanceNext);
   return;
}


This is the definition of GetResult method in IFileOpenDialog's vtable.
I defined GetResultCallback and GetResultNext using the definition of GetResult in the vtable.
(GetResults too.)
Code: Select all
typedef struct IFileOpenDialogVtbl
    {
        BEGIN_INTERFACE

        ... ...
       
        HRESULT ( STDMETHODCALLTYPE *GetResult )(
            __RPC__in IFileOpenDialog * This,
            /* [out] */ __RPC__deref_out_opt IShellItem **ppsi);
       
        ... ...
       
        HRESULT ( STDMETHODCALLTYPE *GetResults )(
            __RPC__in IFileOpenDialog * This,
            /* [out] */ __RPC__deref_out_opt IShellItemArray **ppenum);
       
        HRESULT ( STDMETHODCALLTYPE *GetSelectedItems )(
            __RPC__in IFileOpenDialog * This,
            /* [out] */ __RPC__deref_out_opt IShellItemArray **ppsai);
       
        END_INTERFACE
    } IFileOpenDialogVtbl;



Then, I tested my source code on notepad.exe application.
At first, I opened 'File Open Dialog' in notepad application. When I selected a file, I got the result successfully.
However, if I open 'File Open Dialog' again, the notepad application dies.

I debugged the code using Windbg.
The program successfully opens the file for the first time.
However, if i try opening 'File Open Dialog' after the first time,
the notepad application dies in CoCreateInstanceNext, which belong to CoCreateInstanceCallback.
=> HRESULT hrResult = CoCreateInstanceNext(rclsid, pUnkOuter, dwClsContext, riid, ppv);

GetResults method does not occur the notepad's close.
That's occurred by GetResult method.(IFileOpenDialog::QueryInterface method too.. I had tested..)

1. Are thetre any problems in my source code?
2. Did I define GetResultCallback and GetResultNext correctly?
3. If there is no problem in my source code, do I need to UnHook the methods that I hooked using HookCode?
4. Please tell me why the notepad application dies. Please QQ... :sorry: :sorry: :sorry: :sorry:



* I found additional problem
When I hook the GetResult method and GetResults method together, notepad was closed.
But When I hook the GetResult method only, It's no problem.
Why.... :cry:
DohyunShin
 
Posts: 8
Joined: Thu Oct 20, 2016 2:30 am

Re: HookCode IFileDialog::GetResult problem HELP ME !!

Postby madshi » Thu Oct 27, 2016 6:54 am

Are you sure that the indexes are correct? It seems weird to me that you're using indexes 20 and 27, when it seems that IFileOpenDialog only has 2 methods, according to this:

https://msdn.microsoft.com/en-us/librar ... 2147217396

If IFileOpenDialog has only 2 methods, the indexes should only be 1 apart, not 7.
madshi
Site Admin
 
Posts: 9408
Joined: Sun Mar 21, 2004 5:25 pm

Re: HookCode IFileDialog::GetResult problem HELP ME !!

Postby DohyunShin » Thu Oct 27, 2016 7:51 am

I solved that.

I hooked the Release method and used UnHookCode about the GetResult, GetResults method in the ReleaseCallback.

Release method's index was 2..
...right ? :o

I refer this
This is defined in the ShObjldl.h
Code: Select all
 typedef struct IFileOpenDialogVtbl
    {
        BEGIN_INTERFACE
       
        HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
            __RPC__in IFileOpenDialog * This,
            /* [in] */ __RPC__in REFIID riid,
            /* [annotation][iid_is][out] */
            _COM_Outptr_  void **ppvObject);
       
        ULONG ( STDMETHODCALLTYPE *AddRef )(
            __RPC__in IFileOpenDialog * This);
       
        ULONG ( STDMETHODCALLTYPE *Release )(
            __RPC__in IFileOpenDialog * This);
       
        /* [local] */ HRESULT ( STDMETHODCALLTYPE *Show )(
            IFileOpenDialog * This,
            /* [annotation][unique][in] */
            _In_opt_  HWND hwndOwner);
       
        HRESULT ( STDMETHODCALLTYPE *SetFileTypes )(
            __RPC__in IFileOpenDialog * This,
            /* [in] */ UINT cFileTypes,
            /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec);
       
        HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )(
            __RPC__in IFileOpenDialog * This,
            /* [in] */ UINT iFileType);
       
        HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )(
            __RPC__in IFileOpenDialog * This,
            /* [out] */ __RPC__out UINT *piFileType);
       
        HRESULT ( STDMETHODCALLTYPE *Advise )(
            __RPC__in IFileOpenDialog * This,
            /* [in] */ __RPC__in_opt IFileDialogEvents *pfde,
            /* [out] */ __RPC__out DWORD *pdwCookie);
       
        HRESULT ( STDMETHODCALLTYPE *Unadvise )(
            __RPC__in IFileOpenDialog * This,
            /* [in] */ DWORD dwCookie);
       
        HRESULT ( STDMETHODCALLTYPE *SetOptions )(
            __RPC__in IFileOpenDialog * This,
            /* [in] */ FILEOPENDIALOGOPTIONS fos);
       
        HRESULT ( STDMETHODCALLTYPE *GetOptions )(
            __RPC__in IFileOpenDialog * This,
            /* [out] */ __RPC__out FILEOPENDIALOGOPTIONS *pfos);
       
        HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )(
            __RPC__in IFileOpenDialog * This,
            /* [in] */ __RPC__in_opt IShellItem *psi);
       
        HRESULT ( STDMETHODCALLTYPE *SetFolder )(
            __RPC__in IFileOpenDialog * This,
            /* [in] */ __RPC__in_opt IShellItem *psi);
       
        HRESULT ( STDMETHODCALLTYPE *GetFolder )(
            __RPC__in IFileOpenDialog * This,
            /* [out] */ __RPC__deref_out_opt IShellItem **ppsi);
       
        HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )(
            __RPC__in IFileOpenDialog * This,
            /* [out] */ __RPC__deref_out_opt IShellItem **ppsi);
       
        HRESULT ( STDMETHODCALLTYPE *SetFileName )(
            __RPC__in IFileOpenDialog * This,
            /* [string][in] */ __RPC__in_string LPCWSTR pszName);
       
        HRESULT ( STDMETHODCALLTYPE *GetFileName )(
            __RPC__in IFileOpenDialog * This,
            /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName);
       
        HRESULT ( STDMETHODCALLTYPE *SetTitle )(
            __RPC__in IFileOpenDialog * This,
            /* [string][in] */ __RPC__in_string LPCWSTR pszTitle);
       
        HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )(
            __RPC__in IFileOpenDialog * This,
            /* [string][in] */ __RPC__in_string LPCWSTR pszText);
       
        HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )(
            __RPC__in IFileOpenDialog * This,
            /* [string][in] */ __RPC__in_string LPCWSTR pszLabel);
       
        HRESULT ( STDMETHODCALLTYPE *GetResult )(
            __RPC__in IFileOpenDialog * This,
            /* [out] */ __RPC__deref_out_opt IShellItem **ppsi);
       
        HRESULT ( STDMETHODCALLTYPE *AddPlace )(
            __RPC__in IFileOpenDialog * This,
            /* [in] */ __RPC__in_opt IShellItem *psi,
            /* [in] */ FDAP fdap);
       
        HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )(
            __RPC__in IFileOpenDialog * This,
            /* [string][in] */ __RPC__in_string LPCWSTR pszDefaultExtension);
       
        HRESULT ( STDMETHODCALLTYPE *Close )(
            __RPC__in IFileOpenDialog * This,
            /* [in] */ HRESULT hr);
       
        HRESULT ( STDMETHODCALLTYPE *SetClientGuid )(
            __RPC__in IFileOpenDialog * This,
            /* [in] */ __RPC__in REFGUID guid);
       
        HRESULT ( STDMETHODCALLTYPE *ClearClientData )(
            __RPC__in IFileOpenDialog * This);
       
        HRESULT ( STDMETHODCALLTYPE *SetFilter )(
            __RPC__in IFileOpenDialog * This,
            /* [in] */ __RPC__in_opt IShellItemFilter *pFilter);
       
        HRESULT ( STDMETHODCALLTYPE *GetResults )(
            __RPC__in IFileOpenDialog * This,
            /* [out] */ __RPC__deref_out_opt IShellItemArray **ppenum);
       
        HRESULT ( STDMETHODCALLTYPE *GetSelectedItems )(
            __RPC__in IFileOpenDialog * This,
            /* [out] */ __RPC__deref_out_opt IShellItemArray **ppsai);
       
        END_INTERFACE
    } IFileOpenDialogVtbl;
DohyunShin
 
Posts: 8
Joined: Thu Oct 20, 2016 2:30 am

Re: HookCode IFileDialog::GetResult problem HELP ME !!

Postby madshi » Thu Oct 27, 2016 8:11 am

Oh, you're right about the indexes, my fault.

So are all problems solved now? To be honest, I'm not sure why you would need to unhook in the release method. It shouldn't be necessary.

Have you tried using an "empty" (passthrough) callback function for GetResult(s)? Does that change anything? Also you could try using "PVOID This, PVOID param1" for the parameters of GetResultCallback/Next and GetResultsCallback/Next, just as a test to see if that changes anything. Maybe the compiler does some hidden weird things if you use official interface types.
madshi
Site Admin
 
Posts: 9408
Joined: Sun Mar 21, 2004 5:25 pm

Re: HookCode IFileDialog::GetResult problem HELP ME !!

Postby DohyunShin » Thu Oct 27, 2016 9:18 am

I tested the empty Callback. But It got a same problem. ...
I don't know.. :cry:
and this issue makes me crazy

did i right? am i wrong? :sorry:
DohyunShin
 
Posts: 8
Joined: Thu Oct 20, 2016 2:30 am

Re: HookCode IFileDialog::GetResult problem HELP ME !!

Postby madshi » Thu Oct 27, 2016 9:22 am

Have you tried using PVOID as the parameter type?
madshi
Site Admin
 
Posts: 9408
Joined: Sun Mar 21, 2004 5:25 pm

Re: HookCode IFileDialog::GetResult problem HELP ME !!

Postby DohyunShin » Thu Oct 27, 2016 9:24 am

PVOID?
Like this?
Code: Select all
HRESULT WINAPI GetResultCallback(PVOID This, IShellItem **ppsi)
{
   HRESULT hrResult = GetResultNext(This, ppsi);
   if (!SUCCEEDED(hrResult)) return hrResult;

   DWORD dwPid = GetCurrentProcessId();
   GetResultDataHandle(ppsi, dwPid);

   OutputDebugString(_T("IFileDialog::GetResult End"));
   return hrResult;
}
DohyunShin
 
Posts: 8
Joined: Thu Oct 20, 2016 2:30 am

Re: HookCode IFileDialog::GetResult problem HELP ME !!

Postby madshi » Thu Oct 27, 2016 9:40 am

Something like this:

Code: Select all
HRESULT(WINAPI *GetResultNext)(PVOID This, PVOID ppsi);

HRESULT WINAPI GetResultCallback(PVOID This, PVOID ppsi)
{
   return GetResultNext(This, ppsi);
}

Same with GetResultsCallback/Next. Does the issue still occur then?
madshi
Site Admin
 
Posts: 9408
Joined: Sun Mar 21, 2004 5:25 pm

Re: HookCode IFileDialog::GetResult problem HELP ME !!

Postby DohyunShin » Fri Oct 28, 2016 2:05 am

This Code is fine
Code: Select all
HRESULT(WINAPI *GetResultNext)(PVOID This, PVOID ppsi);
HRESULT(WINAPI *GetResultsNext)(PVOID This, PVOID ppenum);

HRESULT WINAPI GetResultCallback(PVOID This, PVOID ppsi)
{
   HRESULT hrResult = GetResultNext(This, ppsi);
   if (!SUCCEEDED(hrResult)) return hrResult;
   
   return hrResult;       
}
HRESULT WINAPI GetResultsCallback(PVOID This, PVOID ppenum)
{
   HRESULT hrResult = GetResultsNext(This, ppenum);
   if (!SUCCEEDED(hrResult)) return hrResult;
   
   return hrResult;
}


But This code occur the process's close.(same with previous problem. after the first try)
Code: Select all
HRESULT(WINAPI *GetResultNext)(PVOID This, PVOID ppsi);
HRESULT(WINAPI *GetResultsNext)(PVOID This, PVOID ppenum);

HRESULT WINAPI GetResultCallback(PVOID This, PVOID ppsi)
{
   HRESULT hrResult = GetResultNext(This, ppsi);
   if (!SUCCEEDED(hrResult)) return hrResult;

        DWORD dwAddr = reinterpret_cast<DWORD>(This);
   CString strAddr; strAddr.Format(_T("%X"), dwAddr);
   OutputDebugString(_T("GetResult Callback : Address = ") + strAddr);      

   return hrResult;       
}
HRESULT WINAPI GetResultsCallback(PVOID This, PVOID ppenum)
{
   HRESULT hrResult = GetResultsNext(This, ppenum);
   if (!SUCCEEDED(hrResult)) return hrResult;

        DWORD dwAddr = reinterpret_cast<DWORD>(This);
   CString strAddr; strAddr.Format(_T("%X"), dwAddr);
   OutputDebugString(_T("GetResult Callback : Address = ") + strAddr);   

   return hrResult;
}

Between GetResult(s)Next and return, any codes..


In case, There are two IFileOpenDialog Objects A and B. (Both A and B are created by same process.)
Can I hook the object B's GetResult method after hooking object A's ?
(I fialed about this..)

HookCode use address of the object's method.
well, UnHookCode never use address of the specific object's method. right??

then, How do I uninstall the hook of the specific object's method?
DohyunShin
 
Posts: 8
Joined: Thu Oct 20, 2016 2:30 am

Re: HookCode IFileDialog::GetResult problem HELP ME !!

Postby madshi » Fri Oct 28, 2016 9:30 am

DohyunShin wrote:This Code is fine

[...]

But This code occur the process's close.(same with previous problem. after the first try)

[...]


Ah, interesting. So there must be some problem with the CString and/or OutputDebugString() stuff. I don't know what's wrong with that. You could try avoiding CString and use straight APIs instead. E.g. "sprintf_s". Try calling OutputDebugString with a constant string to see if that causes any trouble.

DohyunShin wrote:In case, There are two IFileOpenDialog Objects A and B. (Both A and B are created by same process.)
Can I hook the object B's GetResult method after hooking object A's ?
(I fialed about this..)

HookCode use address of the object's method.
well, UnHookCode never use address of the specific object's method. right??

then, How do I uninstall the hook of the specific object's method?

You're hooking code, not objects, so your hooks will very likely affect all objects. If you only want to hook one specific object, I can see 2 options for that:

1) You could store the "This" pointer somewhere and in your hook callback functions check if it's the right one. It will be a different one for Objects A and B.

2) Or you could try modifying the object's function table directly instead of calling HookCode(). I'm not sure if this would limit the hooks to one object. Maybe. I've never tried this approach yet. Don't have any code for it, either.
madshi
Site Admin
 
Posts: 9408
Joined: Sun Mar 21, 2004 5:25 pm

Re: HookCode IFileDialog::GetResult problem HELP ME !!

Postby DohyunShin » Mon Oct 31, 2016 4:25 am

I tried as mentioned.

This is modified codes.
This code is successful in the notepad. Thank u ! :D
Code: Select all
//Next Methods
HRESULT(WINAPI *GetResultNext)(PVOID This, PVOID ppsi);
HRESULT(WINAPI *GetResultsNext)(PVOID This, PVOID ppsi);
HRESULT(WINAPI *CoCreateInstanceNext)(REFCLSID  rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv);

//Callback Methods
HRESULT WINAPI GetResultCallback(PVOID This, PVOID ppsi)
{
   HRESULT hrResult = GetResultNext(This, ppsi);
   if (!SUCCEEDED(hrResult)) return hrResult;
   
   DWORD dwAddr = reinterpret_cast<DWORD>(This);
   DWORD dwPid = GetCurrentProcessId();
   
   return hrResult;
}
HRESULT WINAPI GetResultsCallback(PVOID This,  PVOID ppenum)
{
   HRESULT hrResult = GetResultsNext(This, ppenum);
   if (!SUCCEEDED(hrResult)) return hrResult;
   
   DWORD dwAddr = reinterpret_cast<DWORD>(This);
   DWORD dwPid = GetCurrentProcessId();

   return hrResult;
}
HRESULT WINAPI CoCreateInstanceCallback(
   REFCLSID  rclsid,
   LPUNKNOWN pUnkOuter,
   DWORD     dwClsContext,
   REFIID    riid,
   LPVOID    *ppv
) {
   HRESULT hrResult = CoCreateInstanceNext(rclsid, pUnkOuter, dwClsContext, riid, ppv);
   
   if (hrResult == S_OK && rclsid == CLSID_FileOpenDialog) {
      DWORD dwAddr = reinterpret_cast<DWORD>(*(&(*ppv)));
   
      LPVOID pGetResult;
      LPVOID pGetResults;
      
#ifdef WIN64
      pGetResult = GetInterfaceMethod64(*ppv, 20);
      pGetResults = GetInterfaceMethod64(*ppv, 27);
#else
      pGetResult = GetInterfaceMethod(*ppv, 20);
      pGetResults = GetInterfaceMethod(*ppv, 27);
#endif
      HookCode(pGetResult, GetResultCallback, (PVOID *)&GetResultNext);
      HookCode(pGetResults, GetResultsCallback, (PVOID *)&GetResultsNext);
   }
   return hrResult;
}

//Hook Install & Uninstall
BOOL InstallAPIHook()
{
   if (!HookAPI("Comdlg32.dll", "GetOpenFileNameW", GetOpenFileNameWCallback, (PVOID*)&GetOpenFileNameWNext))
      OutputDebugString(_T("[hookofficepro] GetOpenFileNameW Hook Fail"));
   else
      OutputDebugString(_T("[hookofficepro] GetOpenFileNameW Hook Success"));
   
   if (!HookAPI("Ole32.dll", "CoCreateInstance", CoCreateInstanceCallback, (PVOID*)&CoCreateInstanceNext))
      OutputDebugString(_T("[hookofficepro] CoCreateInstance Hook Fail"));
   else
      OutputDebugString(_T("[hookofficepro] CoCreateInstance Hook Success"));
   
   return TRUE;
}

void UninstallAPIHook() {
   UninstallHookCode(&GetOpenFileNameWNext);
   UninstallHookCode(&CoCreateInstanceNext);
   OutputDebugString(_T("[hookofficepro] UninstallHookCode"));
   return;
}


I need to hook all process besides the notepad.
So I tested this code in other messenger program.
But I got a same problem... Is there problem in the messenger programme?

if the messenger has protection, it must be failed if i hooked Realese method, but it succeeded.
So I guess. This is problem of the messenger's internecine structure.

If I unhook the GetResult(s)Next methods in the ReleaseCallback, does it cause fatal problem?
DohyunShin
 
Posts: 8
Joined: Thu Oct 20, 2016 2:30 am

Re: HookCode IFileDialog::GetResult problem HELP ME !!

Postby madshi » Mon Oct 31, 2016 8:53 am

I'm not aware of any specific messenger related problem.

Unhooking GetResult(s) in the ReleaseCallback might not be ideal, but I suppose it should work.
madshi
Site Admin
 
Posts: 9408
Joined: Sun Mar 21, 2004 5:25 pm

Re: HookCode IFileDialog::GetResult problem HELP ME !!

Postby iconic » Mon Oct 31, 2016 10:03 pm

I'd give modifying the vtable a go. You already know the indexes, if I indeed read correctly. See here about vtable http://bbs.csdn.net/topics/391065069

P.S: The example code does exactly what you're in need of, just use GetResult instead of GetResult"s"

P.P.S: See here too http://add2paper.github.io/2015/06/24/H ... -Functions

--Iconic
iconic
 
Posts: 808
Joined: Wed Jun 08, 2005 5:08 am


Return to madCodeHook

Who is online

Users browsing this forum: No registered users and 4 guests