nektra / Deviare2

Deviare API Hook
http://www.nektra.com/products/deviare-api-hook-windows/
Other
448 stars 127 forks source link

Hooking undocumented functions and adding new functions into nektra's database #41

Closed eduardonatan closed 5 years ago

eduardonatan commented 5 years ago

Hello everyone!

I'm trying to hook some functions of the spoolsv.exe process, for instance the YSetJob and YGetJob functions (both undocumented). So far I'm abble to get the calls, but when I try to get the params through: INktParamsEnum paramsEnum = hookCallInfo.Params(); nothing is returned. I believe that I have to insert these functions into the nektras database, still, I don't even know where to begin with and actually I'm not entirely sure if this is the real problem here

Please, help! Using C# and Visual Studio 2013 in this one.

mxmauro commented 5 years ago

Hi @eduardonatan . In the distribution package you will see a Database folder. Inside the headers, you must add the C definition of the API you want to add. Then there is a batch file to preprocess those files and other set of bat files to rebuild the database.

eduardonatan commented 5 years ago

Hello there @mxmauro ! Thanks for the reply

I added the C definitions into "...\Deviare2-master\Deviare2-master\Database\HeaderBuilder\Full\headers.h" file, for instance PrvGetJobW function

__stdcall BOOL PrvGetJobW(
  _In_  HANDLE  hPrinter,
  _In_  DWORD   JobId,
  _In_  DWORD   Level,
  _Out_ LPBYTE  pJob,
  _In_  DWORD   cbBuf,
  _Out_ LPDWORD pcbNeeded
);

Then I saved the file and executed the bats files: "..\Deviare2-master\Database\HeaderBuilder\build32.bat" "..\Deviare2-master\Database\HeaderBuilder\build64.bat"

After that I executed: "...\Deviare2-master\Database\DbBuilder\build_db32.bat" "...\Deviare2-master\Database\DbBuilder\build_db64.bat"

But it seems that the DBs files inside "..\Deviare2-master\bin" are not being generated properly

I don't know if I'm executing the batchs in the right order, or the correct ones

mxmauro commented 5 years ago

Hi Eduardo. Databases are not copied to bin folder. Look for them inside Database folder or some of its ssubfolders.

eduardonatan commented 5 years ago

Hi @mxmauro thanks for the quick answer. Can't find the db files, I believe that the bats are not beeing executed properly, is that order that I mentioned correct ? I'm not able to find the preprocessed files either

eduardonatan commented 5 years ago

the build64.bat is giving me:

Use: BUILD64 namespace Where 'namespace' should be set to "base" to build base headers

mxmauro commented 5 years ago

Yes, you see base and full folders (you can create another branch if you want)

namespace is the name of the folder you want to process.

eduardonatan commented 5 years ago

Oh, of course, feel so stupid :| Now I'm getting another error when running "build64.bat Full" The output is:

Compiling headers... Fixing headers... The system cannot find the path specified. The system cannot find the path specified.

Looks like its not finding "\bin\HeaderFix.exe" When Fixing the headers

mxmauro commented 5 years ago

If you downloaded/cloned the source code, then you have to build most of binaries. Ensure all projects in different VS solutions are selected when you do a batch build.

eduardonatan commented 5 years ago

Hello again @mxmauro Finally I was able to add the functions definitions in the .db file Then I just replaced the db file in my application for the new one

Still, I can't get the params when the functions are called, am I forgetting something here?

mxmauro commented 5 years ago

Is PrvGetJobW exported by the dll? How are you creating the hook? Using CreateHookForAddress?

eduardonatan commented 5 years ago

Yes, It is exported I'm creating like this:

NktHook hook = _spyMgr.CreateHook("spoolsv.exe!PrvGetJobW", (int)(eNktHookFlags.flgRestrictAutoHookToSameExecutable | eNktHookFlags.flgOnlyPreCall));

hook.Hook(true);            
hook.Attach(_process, true);

I opened the database with a sqlite tool and was able to find the functions that I added, Still, no luck getting the params on my application ;(

mxmauro commented 5 years ago

Try putting the definition enclosed in extern "C" to avoid C++ artifacts introduced by the GCC compiler

eduardonatan commented 5 years ago

Tried, no luck I executed the following statement:

NktDbObjectsEnum funcs = _spyMgr.DbFunctions(64);
foreach (NktDbObject dbObj in funcs)
          System.Diagnostics.Debug.WriteLine(dbObj.Name);

And could NOT find the functions that I added But on the .sqlite file generated by build_db64.bat I'm able to find them.

I'm copying the .db files generated to my project bin folder, same directory of: DvAgent64.dll DvAgent.dll Nektra.Deviare2.dll DeviareCOM64.dll

I dont know if I have to build some of these .dlls again, now with my .db file

eduardonatan commented 5 years ago

No matter what .dbs files I use _spyMgr.DbFunctions(64);

Always returns the same functions

mxmauro commented 5 years ago

Can you upload me the generated sqlite and db? Also the steps you type to create the DB and where do you add the function signature.

(Use something like wetransfer or google drive and share the linnk)

eduardonatan commented 5 years ago

I created the folder ...\Deviare2-master\Database\HeaderBuilder\Custom Inside this directory a created a header.h file with my functions signatures: header.h

Then, I run...\Deviare2-master\Database\HeaderBuilder\buildall.bat Custom This generated the following files in folder ...\Deviare2-master\Database\HeaderBuilder\Custom\output : preprocessed32W.h preprocessed64W.h

After this, I edited the ...\Deviare2-master\Database\DbBuilder\build_db64.bat to get the headers from Custom folder instead of Full: build_db64.bat

Then I corrected some errors in the preprocessed64W.h (some functions were defined with two return types likeint double function()...;), none related to the functions that I added.

After that I executed: ...\Deviare2-master\Database\DbBuilder\build_db64.bat Here are the logs: DbGenerator64.log ...This took several minutes

Then I found the .db and .sqlite files generated by the command inside: ...\Deviare2-master\Database\DbBuilder: deviare64.sqlite deviare64.db

Finally, I just copied the deviare64.db file generated to my project, inside my bin folder, with all the .dll files from deviare

If I missed something, please let me know!

mxmauro commented 5 years ago

Hi @eduardonatan please try modifying config.xml and add inside <modules> a module containing the full path to SPOOLSV.EXE

And sorry for the silly question: Are you testing on a 64-bit OS, right?

eduardonatan commented 5 years ago

Yes, 64bits The funny thing is that the function PrvStartDocPrinterW, already shipped with the API, and presented into Full/headers.h file works fine! And it is also exported by spoolsv.exe.

That's why I figured that I should just add the other definitions bellow PrvStartDocPrinterW, in the Full Headers. That did not work, then a created the Custom/headers.h to make the process a little bit faster, with fewer modules and headers, not a success either.

mxmauro commented 5 years ago

Hi @eduardonatan I replaced the DB and used CSharpConsole64 to hook spooler's PrvGetJobW and the function has the parameters as expected.

I recommend to monitor your app with procmon to see if the correct database is being opened.

image

eduardonatan commented 5 years ago

Hello @mxmauro Sorry for the delay! I got it working (finally), the problem was that Nektra.Deviare2 was using the wrong database, it was being referenced to another folder outside my project, and it was not using the .db files that were inside my bin folder, but the ones with Nektra.Deviare2.dll directory.

In my defense, I'm pretty new at .NET development 🤦‍♂️

Thanks A LOT for all the support you gave me!

mxmauro commented 5 years ago

Hahaha no problem!

Good luck.