EasyHook DrawTextW user32.dll Injection, Application crashing - easyhook

I'm using EasyHook too hook calls to DrawTextW, while testing with notepad, if I open Help -> About, It captures all the text that appears on the screen as expected. However, if I open File -> Open, Notepad crashes. I don't expect it to capture any text, but I can't understand why notepad is crashing. Any help would be appreciated.
using EasyHook;
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using UI;
namespace MyClassLibrary
{
public class Main : IEntryPoint
{
[StructLayout(LayoutKind.Sequential)]
public struct HDC__
{
public int unused;
}
[StructLayout(LayoutKind.Sequential)]
public struct tagRECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll", EntryPoint = "DrawTextW")]
public static extern int DrawTextW([In()] IntPtr hdc, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpchText, int cchText, ref tagRECT lprc, uint format);
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
public delegate int TDrawTextW(
[In()] IntPtr hdc,
[MarshalAs(UnmanagedType.LPWStr)]
StringBuilder lpchText,
int cchText,
ref tagRECT lprc,
uint format);
static string ChannelName;
RemoteMon Interface;
LocalHook DrawTextWHook;
public Main(RemoteHooking.IContext InContext, String InChannelName)
{
try
{
Interface = RemoteHooking.IpcConnectClient<RemoteMon>(InChannelName);
ChannelName = InChannelName;
Interface.IsInstalled(RemoteHooking.GetCurrentProcessId());
}
catch (Exception ex)
{
Interface.ErrorHandler(ex);
}
}
static int hkDrawTextW(
[In()] IntPtr hdc,
[MarshalAs(UnmanagedType.LPWStr)]
StringBuilder lpchText,
int cchText,
ref tagRECT lprc,
uint format)
{
try
{
((Main)HookRuntimeInfo.Callback).Interface.GotDrawTextW(lpchText);
return DrawTextW(hdc, lpchText, cchText, ref lprc, format);
}
catch (Exception ex)
{
((Main)HookRuntimeInfo.Callback).Interface.ErrorHandler(ex);
return 0;
}
}
public void Run(RemoteHooking.IContext InContext, String InChannelName)
{
try
{
DrawTextWHook = LocalHook.Create(LocalHook.GetProcAddress("user32.dll", "DrawTextW"),
new TDrawTextW(hkDrawTextW), this);
DrawTextWHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
}
catch (Exception ex)
{
Interface.ErrorHandler(ex);
}
try
{
RemoteHooking.WakeUpProcess();
}
catch (Exception ex)
{
Interface.ErrorHandler(ex);
}
while (true)
{
Thread.Sleep(10000);
}
}
}
}

There is a problem with marshalling the text to a StringBuilder when the Open dialog shows. I'm not 100% sure of the reason, but perhaps the difference between a COM initialised string and one initialised with malloc? I have experienced marshalling issues with strings in the past depending on how their underlying memory has been initialised.
The solution is to use a String instead of a StringBuilder for the text parameter. Replace the extern and the delegate and other appropriate areas with a string parameter:
[DllImport("user32.dll", EntryPoint = "DrawTextW")]
public static extern int DrawTextW([In()] IntPtr hdc, [MarshalAs(UnmanagedType.LPWStr)] String lpchText, int cchText, ref tagRECT lprc, uint format);
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
public delegate int TDrawTextW(
[In()] IntPtr hdc,
[MarshalAs(UnmanagedType.LPWStr)]
String lpchText,
int cchText,
ref tagRECT lprc,
uint format);
static int hkDrawTextW(
[In()] IntPtr hdc,
[MarshalAs(UnmanagedType.LPWStr)]
String lpchText,
int cchText,
ref tagRECT lprc,
uint format)
{
...
}

Related

Is it possible to set a title for a .NET Core host process (dotnet.exe) in console app?

I'm trying to set it via command argument – --title="Host1" but it doesn't work. As you can see it is possible for ASP.NET Core application:
Any other options? I have a lot of console processes on my machine and want to assign friendly names to them.
Add this class in your project
#if DEBUG
delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
public class DebuggerForm
{
const UInt32 WS_EX_NOACTIVATE = 0x08000000;
const UInt32 WS_MINIMIZE = 0x20000000;
const int SW_SHOWMINNOACTIVE = 7;
const UInt32 WM_DESTROY = 2;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct WNDCLASSEX
{
[MarshalAs(UnmanagedType.U4)]
public int cbSize;
[MarshalAs(UnmanagedType.U4)]
public int style;
public IntPtr lpfnWndProc;
public int cbClsExtra;
public int cbWndExtra;
public IntPtr hInstance;
public IntPtr hIcon;
public IntPtr hCursor;
public IntPtr hbrBackground;
public string lpszMenuName;
public string lpszClassName;
public IntPtr hIconSm;
}
private WndProc delegWndProc = myWndProc;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
static extern bool DestroyWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true, EntryPoint = "CreateWindowEx")]
public static extern IntPtr CreateWindowEx(UInt32 dwExStyle, UInt16 lpClassName, string lpWindowName, UInt32 dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
[DllImport("user32.dll", SetLastError = true, EntryPoint = "RegisterClassEx")]
static extern System.UInt16 RegisterClassEx([In] ref WNDCLASSEX lpWndClass);
[DllImport("kernel32.dll")]
static extern uint GetLastError();
[DllImport("user32.dll")]
static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
internal bool Create(string name)
{
WNDCLASSEX windowClass = new WNDCLASSEX();
windowClass.cbSize = Marshal.SizeOf(typeof(WNDCLASSEX));
windowClass.style = 0;
windowClass.hbrBackground = IntPtr.Zero;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = Marshal.GetHINSTANCE(this.GetType().Module);
windowClass.hIcon = IntPtr.Zero;
windowClass.hCursor = IntPtr.Zero;
windowClass.lpszMenuName = null;
windowClass.lpszClassName = "DebuggerForm";
windowClass.lpfnWndProc = Marshal.GetFunctionPointerForDelegate(delegWndProc);
windowClass.hIconSm = IntPtr.Zero;
ushort regResult = RegisterClassEx(ref windowClass);
if (regResult == 0)
{
uint error = GetLastError();
return false;
}
string wndClass = windowClass.lpszClassName;
IntPtr hWnd = CreateWindowEx(WS_EX_NOACTIVATE, regResult, name, WS_MINIMIZE, 0, 0, 200, 200, IntPtr.Zero, IntPtr.Zero, windowClass.hInstance, IntPtr.Zero);
if (hWnd == ((IntPtr)0))
{
uint error = GetLastError();
return false;
}
ShowWindow(hWnd, SW_SHOWMINNOACTIVE);
return true;
}
private static IntPtr myWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
switch (msg)
{
case WM_DESTROY:
DestroyWindow(hWnd);
break;
default:
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}
#endif
And in Startup.cs in the constructor add
new DebuggerForm().Create("WebApp");
this will show the processs title as WebApp.

How to write a dummy network device driver

I'm trying to write a dummy network driver and have written the code, but I'm facing issue while trying to load driver i.e. it's crashing the kernel sometimes and sometimes it doesn't respond.
Dummy device code
#include <linux/module.h>
#include <linux/netdevice.h>
int virtualNIC_open(struct net_device *dev) {
printk("virtualNIC_open called\n");
netif_start_queue(dev);
return 0;
}
int virtualNIC_release(struct net_device *dev) {
printk("virtualNIC_release called\n");
netif_stop_queue(dev);
return 0;
}
int virtualNIC_xmit(struct sk_buff *skb, struct net_device *dev) {
printk("dummy xmit function called...\n");
dev_kfree_skb(skb);
return 0;
}
int virtualNIC_init(struct net_device *dev);
const struct net_device_ops my_netdev_ops = {
.ndo_init = virtualNIC_init,
.ndo_open = virtualNIC_open,
.ndo_stop = virtualNIC_release,
.ndo_start_xmit = virtualNIC_xmit,
};
int virtualNIC_init(struct net_device *dev) {
dev->netdev_ops = &my_netdev_ops;
printk("virtualNIC device initialized\n");
}
struct net_device virtualNIC = {
.netdev_ops = &my_netdev_ops,
/* .netdev_ops.ndo_init: virtualNIC_init*/
};
int virtualNIC_init_module(void) {
int result;
strcpy(virtualNIC.name, "virtualNIC");
if((result = register_netdev(&virtualNIC))) {
printk("virtualNIC: Error %d initalizing card ...", result);
return result;
}
return 0;
}
void virtualNIC_cleanup (void)
{
printk ("<0> Cleaning Up the Module\n");
unregister_netdev (&virtualNIC);
return;
}
module_init(virtualNIC_init_module);
module_exit(virtualNIC_cleanup);
MODULE_LICENSE("GPL");
Please help me to figure, where I'm going wrong.
Thanks in Advance
There is already network dummy codec in the mainline kernel. But still if you want to write for the practice. Then I think you can proceed with your own driver as well.
I have modified some of things in your driver. I think you can give one try to it see whether you can see the dummy interface in your ifconfig or not. It is just a sample code (for the interface entry in the ifconfig) and I am not handling any kind of locking or network packet transmission or reception.
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/kernel.h>
#include <linux/etherdevice.h>
struct net_device *virtualNIC;
int virtualNIC_open(struct net_device *dev) {
printk("virtualNIC_open called\n");
return 0;
}
int virtualNIC_release(struct net_device *dev) {
printk("virtualNIC_release called\n");
netif_stop_queue(dev);
return 0;
}
int virtualNIC_xmit(struct sk_buff *skb, struct net_device *dev) {
printk("dummy xmit function called...\n");
dev_kfree_skb(skb);
return 0;
}
const struct net_device_ops my_netdev_ops = {
.ndo_init = virtualNIC_init,
.ndo_open = virtualNIC_open,
.ndo_stop = virtualNIC_release,
.ndo_start_xmit = virtualNIC_xmit,
};
int virtualNIC_init(struct net_device *dev) {
printk("virtualNIC device initialized\n");
return 0;
};
static void virtual_setup(struct net_device *dev){
dev->netdev_ops = &my_netdev_ops;
}
int virtualNIC_init_module(void) {
int result;
virtualNIC = alloc_netdev(0, "virtnC%d", virtual_setup);
if((result = register_netdev(virtualNIC))) {
printk("virtualNIC: Error %d initalizing card ...", result);
return result;
}
return 0;
}
void virtualNIC_cleanup (void)
{
printk ("<0> Cleaning Up the Module\n");
unregister_netdev (virtualNIC);
}
module_init(virtualNIC_init_module);
module_exit(virtualNIC_cleanup);
MODULE_LICENSE("GPL");
This is very helpful, I just want to add this part of code:
virtualNIC = alloc_netdev (0, "virtnC%d", NET_NAME_UNKNOWN, virtual_setup);
this has 4 parameter in new kernel...

Passing a QObject to an Script function with QJSEngine?

I'm trying to call a function in an external script while passing a QObject as a parameter.
My QObject is defined as this:
#ifndef INSERTVALUES_H
#define INSERTVALUES_H
#include <QObject>
struct insertValueDef
{
QString name;
QString xmlCode;
QString value;
bool key;
bool insert;
};
typedef insertValueDef TinsertValueDef;
class insertValues : public QObject
{
Q_OBJECT
public:
explicit insertValues(QObject *parent = 0);
~insertValues();
void insertValue(TinsertValueDef value);
int count();
void setItemName(int index, QString name);
void setItemXMLCode(int index, QString xmlCode);
void setItemValue(int index, QString value);
void setItemIsKey(int index, bool isKey);
void setItemToInsert(int index, bool toInsert);
QString itemName(int index);
QString itemXMLCode(int index);
QString itemValue(int index);
bool itemIsKey(int index);
bool itemToInsert(int index);
bool valueIsNumber(int index);
int getIndexByColumnName(QString name);
private:
QList<TinsertValueDef> m_insertList;
};
#endif // INSERTVALUES_H
My JS Script function is this:
function beforeInsert(table,data)
{
if (table == "tmpTable")
{
var index = data.getIndexByColumnName("tmpfield");
if (index >= 0)
{
data.setItemValue(index,"Carlos Quiros");
}
}
}
The code that runs runs the script is the following:
QFile scriptFile(javaScript);
if (!scriptFile.open(QIODevice::ReadOnly))
{
log("Error: Script file defined but cannot be opened");
return 1;
}
JSEngine.evaluate(scriptFile.readAll(), javaScript);
scriptFile.close();
insertValues insertObject;
TinsertValueDef tfield;
tfield.key = false;
tfield.name = "tmpfield";
tfield.xmlCode = "tmpCode";
tfield.value = "tmpValue";
tfield.insert = true;
insertObject.insertValue(tfield);
QString error;
beforeInsertFunction = JSEngine.evaluate("beforeInsert",error);
if (!beforeInsertFunction.isError())
{
QJSValue insertListObj = JSEngine.newQObject(&insertObject);
QJSValue result = beforeInsertFunction.call(QJSValueList() << "tmpTable" << insertListObj);
if (result.isError())
{
log("Error calling BeforInsert JS function.");
return 1;
}
else
{
log("JS function seems to be ok");
for (int pos = 0; pos < insertObject.count(); pos++)
{
log(insertObject.itemName(pos) + "-" + insertObject.itemValue(pos));
}
return 1;
}
}
else
{
log("Error evaluating BeforInsert JS function. [" + error + "]");
return 1;
}
I can see that the parameter "table" is passing properly but the rest of the code is not working. I guess I cannot do:
var index = data.getIndexByColumnName("tmpfield");
Any idea what am I doing wrong? and what else should I do to make it work?
Thanks,
In order to access properties or invoke methods of QObjects passed to QJSEngine (or to QML), you need to declare them using Q_PROPERTY and Q_INVOKABLE macros in your QObject-derived class declaration.
Please see the Qt documentation for more details: Exposing Attributes of C++ Types to QML

How do i get this 2 dimensional array to display as a table?

I need to make a table of seats with varying prices. Heres what i got so far. Im having trouble producing a table.
public class theatSeat {
public static final int rows=9;
public static final int cols=10;
public static void dispBox(int[][] a){
for (int row=0;row<rows;row++){
System.out.print((row+1)+" ");
for (int col=0;col<cols;col++){
System.out.print(a[row][col]+" ");
System.out.println();
}
}
}//Sets the diplayed seating box
public static void getPrice(int[][]a){
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] [] table = new int[rows] [cols];
for(int row=0;row<rows;row++){
for(int col=0;col<cols;col++){
table[row][col]=0;
}
}
dispBox(table);
}}//fin.
In your loop, you're making all the values 0. Did you want something like random value for each? Like this
Random random = new Random();
for(int row=0;row<rows;row++){
for(int col=0;col<cols;col++){
table[row][col]=random.nextInt(50);
}
}
If you're having problems with displaying, try this
public static void dispBox(int[][] a){
for (int row=0;row<rows;row++){
System.out.print((row+1)+" ");
for (int col=0;col<cols;col++){
System.out.print(a[row][col]+" ");
}
System.out.println();
// this needs to go at the end of each line.
// You were putting it at the end of each print
}
}

Function from C# to C++ via Qt lib

Could you tell me how these function from C# can be re-written to C++ via Qt lib?
private MemoryStream _memoryStream= new MemoryStream();
//WriteUTFBytes
public void WriteUTFBytes(string value)
{
//Length - max 65536.
UTF8Encoding utf8Encoding = new UTF8Encoding();
byte[] buffer = utf8Encoding.GetBytes(value);
if (buffer.Length > 0)
WriteBytes(buffer);
}
//WriteBytes
public void WriteBytes(byte[] buffer)
{
for (int i = 0; buffer != null && i < buffer.Length; i++)
_memoryStream.WriteByte(buffer[i]);
}
//WriteByte
public void WriteByte(int value)
{
_memoryStream.WriteByte((byte)value);
}
//WriteShort
public void WriteShort(int value)
{
byte[] bytes = BitConverter.GetBytes((ushort)value);
WriteBigEndian(bytes);
}
//WriteBigEndian
private void WriteBigEndian(byte[] bytes)
{
if (bytes == null)
return;
for (int i = bytes.Length - 1; i >= 0; i--)
{
_memoryStream.WriteByte(bytes[i]);
}
}
private:
QBuffer _buffer;
public:
YourClass()
{
_buffer.open(QIODevice::WriteOnly);
}
void writeUtfBytes(const QString &value)
{
QTextStream ts(&_buffer);
ts.setCodec("UTF-8");
ts << value;
}
void writeBytes(const char *data, int size)
{
if (data)
_buffer.write(data, size);
}
void writeByte(int value)
{
_buffer.putChar(value);
}
void writeShort(int value)
{
_buffer.putChar(value >> 8);
_buffer.putChar((char) value);
}

Resources