Extending packet header from within a Netfilter hook - network-programming

I want to prepend IP header on an existing IP packet while inside NF_HOOK_LOCAL_OUT. The issue I face is that the skb expansion functions (such as copy/clone/expand/reallocate header) allocate a new sk_buff. We can not return this newly allocated pointer since netfilter hook function no longer (kernel version 2.6.31) passes the skb pointer's address (passes by value). How I solved the issue is as follows:
1. I got a new skb using skb_header_realloc(). This copies all the data from skb.
2. I modified the new skb (call it skb2) to prepend the new IP header, set appropriate values in the new IP header.
3. Replace the contents of the original skb (passed in the Netfilter hook function) with the contents of the skb2 using skb_morph(). Returned NF_ACCEPT.
Is this the only way of achieving what I intended to? Is there a more efficient solution? Are there other use cases of skb_morph (besides the IP reassembly code)?

This works for me, in 2.6 kernels:
...
struct iphdr* iph;
if (skb_headroom(skb) < sizeof(struct iphdr))
if (0 != pskb_expand_head(skb, sizeof(struct iphdr) - skb_headroom(skb), 0, GFP_ATOMIC)) {
printk("YOUR FAVOURITE ERROR MESSAGE");
kfree_skb(skb);
return NF_STOLEN;
}
iph = (struct iphdr*) skb_push(skb, sizeof(struct iphdr));
//Fill ip packet
return NF_ACCEPT;
Hope it helps.

Related

Testing for GVfs metadata support in C

I am trying to add support for per-directory viewing settings to the Thunar file browser of the Xfce desktop. So for example if a user chooses to view the contents of a directory as a list rather than as a grid of icons, this setting is remembered for that directory and will be used whenever that directory is viewed.
Now Thunar is built on GLib, and the mechanism we have chosen to use to implement this is to store metadata using GFile attributes, using methods like g_file_set_attributes_async to store
keys with names such as "metadata::thunar-view-type". The per-directory feature can be turned on or off by the user via a checkbox in a preferences dialog. My knowledge of GIO and GLib is pretty limited, but I have now managed to get this all working as desired (you can see my merge request here if you are interested).
Now as I understand it, the functionality that I am using here relies on something called "GVfs metadata", and as I understand it this might not be available on all systems. On systems where GVfs metadata is not available, I want to turn this functionality off and in particular make the checkbox in the preferences dialog insensitive (i.e. greyed out). Thus I need to write a function to detect if gvfs metadata support is available, by which I mean whether I can use functions like g_file_set_attributes_async to successfully save metadata so that it will be available in future.
Thunar is written in C, so this function needs to be written in C using the C API for GLib, GIO, etc.
The function I have come up with (from much reading of API documentation, modifying code scraps I have found, and experimentation) is as follows.
gboolean
thunar_g_vfs_metadata_is_supported (void)
{
GDBusMessage *send, *reply;
GDBusConnection *conn;
GVariant *v1, *v2;
GError *error = NULL;
const gchar **service_names;
gboolean metadata_found;
/* connect to the session bus */
conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
/* check that the connection was opened sucessfully */
if (error != NULL)
{
g_error_free (error);
return FALSE;
}
/* create the message to send to list the available services */
send = g_dbus_message_new_method_call ("org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus",
"ListNames");
/* send the message and wait for the reply */
reply = g_dbus_connection_send_message_with_reply_sync (conn, send, G_DBUS_SEND_MESSAGE_FLAGS_NONE,
-1, NULL, NULL, &error);
/* release the connection and the sent message */
g_object_unref (send);
g_object_unref (conn);
/* check if we got a sucessful reply */
if (error != NULL)
{
g_error_free (error);
return FALSE;
}
/* extract the GVariant with the array of strings describing the available services */
v1 = g_dbus_message_get_body (reply); /* v1 belongs to reply and must not be freed */
if (v1 == NULL || !g_variant_is_container (v1) || g_variant_n_children (v1) < 1)
{
g_object_unref (reply);
return FALSE;
}
v2 = g_variant_get_child_value (v1, 0);
g_object_unref (reply);
/* check that the GVariant we have been given does contain an array of strings */
if (!g_variant_is_of_type (v2, G_VARIANT_TYPE_STRING_ARRAY))
{
g_variant_unref (v2);
return FALSE;
}
/* search through the list of service names to see if gvfs metadata is present */
metadata_found = FALSE;
service_names = g_variant_get_strv (v2, NULL);
for (int i=0; service_names[i] != NULL; i++)
if (g_strcmp0 (service_names[i], "org.gtk.vfs.Metadata") == 0)
metadata_found = TRUE;
g_free (service_names);
g_variant_unref (v2);
return metadata_found;
}
As you can see, this function uses DBus to query service names to see if the necessary service is available. Now, as far as I have been able to test it, this function works as I want it to. However, during a code review it has been questioned whether this can be done without relying on DBus (which might itself not be available even though GVfs metadata is).
Thus (at last!) my question: what is the best (i.e. most robust and accurate) way to test for GVfs metadata support via the C API for GLib, GIO, etc?. As I said above, by "GVfs metadata support" I mean "can I use functions like g_file_set_attributes_async to successfully save metadata so that it will be available in future?".
One method I have considered is looking at the list of running processes for the name "gvfsd-metadata", but that seems a bit kludgy to me.
Also, as mentioned above I am very much a novice with these technologies, so I is absolutely possible that I have misunderstood stuff here, so if you spot any errors in the assertions I have made above, please let me know.
Thanks!
(And yes, usual story, I'm a long time reader of SO & co, but a first time asker, so please feel free to edit or let me know if I've done something wrong/bad)
Call g_file_query_settable_attributes() and g_file_query_writable_namespaces() on the GFile, as described in the GFileInfo documentation:
However, not all attributes can be changed in the file. For instance, the actual size of a file cannot be changed via g_file_info_set_size(). You may call g_file_query_settable_attributes() and g_file_query_writable_namespaces() to discover the settable attributes of a particular file at runtime.

starting a process with exactly the same address structure as previous openning

Is it possible to start a process in windows with exactly the same address structure as the previous opening of the process?
To clarify the goal of this question I should mention that I use cheatengine (http://www.cheatengine.org/) to cheat some games! It includes several iterations to find a parameter (e.g. ammunition) and freeze it. However, each time I restart the game, since the memory structure of the game changes, I need to go through the time-consuming iterations again. So, if there were a method bring up the game exactly with the same memory structure as before, I wouldn't need going through iterations.
Not to say it's impossible, but this is essentially too much work due to the dynamic memory allocation routines the process will be using including the new operator and malloc(). Additionally when the DLL's imported by the executable are loaded into memory they have a preferred imagebase but if that address is already used, the OS will load it into a different memory location. Additionally Address Space Layout Randomization (ASLR) can be enabled on the process which is a security measure that randomizes the memory address of code sections.
The solution to your problem is much easier then what you're asking. To defeat the dynamic memory allocation described above you can still resolve the correct address of a variable by utilizing:
Relative offsets from module bases
Multi-level pointers
Pattern Scanning
Cheat Engine has all 3 of these built into it. When you save an address to your table is often saves it as a module + relative offset. You can pointer scan for the address and save it as a multilevel pointer or reverse the pointer yourself and manually place it in the table. Pattern scanning is achieved by using a CE Script, which you can put right in the Cheat Table.
In this case the ammo variable, may be a "static address" which means it's relative to the base address of the module. you may see it listed in Cheat Engine as "client.dll + 0xDEADCODE". You simply get the base address of the module at runtime and add the relative offset.
If you're looking to make an external hack in C++ you can get started like this.
In an external hack you do this by walking a ToolHelp32Snapshot:
uintptr_t GetModuleBase(const wchar_t * ModuleName, DWORD ProcessId) {
// This structure contains lots of goodies about a module
MODULEENTRY32 ModuleEntry = { 0 };
// Grab a snapshot of all the modules in the specified process
HANDLE SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessId);
if (!SnapShot)
return NULL;
// You have to initialize the size, otherwise it will not work
ModuleEntry.dwSize = sizeof(ModuleEntry);
// Get the first module in the process
if (!Module32First(SnapShot, &ModuleEntry))
return NULL;
do {
// Check if the module name matches the one we're looking for
if (!wcscmp(ModuleEntry.szModule, ModuleName)) {
// If it does, close the snapshot handle and return the base address
CloseHandle(SnapShot);
return (DWORD)ModuleEntry.modBaseAddr;
}
// Grab the next module in the snapshot
} while (Module32Next(SnapShot, &ModuleEntry));
// We couldn't find the specified module, so return NULL
CloseHandle(SnapShot);
return NULL;
}
To get the Process ID you would do:
bool GetPid(const wchar_t* targetProcess, DWORD* procID)
{
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snap && snap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
if (Process32First(snap, &pe))
{
do
{
if (!wcscmp(pe.szExeFile, targetProcess))
{
CloseHandle(snap);
*procID = pe.th32ProcessID;
return true;
}
} while (Process32Next(snap, &pe));
}
}
return false;
}
Using my example you would combine these functions and do:
DWORD procId;
GetPid(L"game.exe", &procId);
uintptr_t modBaseAddr = GetModuleBase(L"client.dll", procId);
uintptr_t ammoAddr = modBaseAddr + 0xDEADCODE;
If the address is not "static" you can find a pointer to it, the base address of the pointer must be static and then you just follow the above guide, and dereference each level of the pointer and add an offset.
Of course I have a function for that too :)
uintptr_t FindDmaAddy(HANDLE hProcHandle, uintptr_t BaseAddress, uintptr_t Offsets[], int PointerLevel)
{
uintptr_t pointer = BaseAddress;
uintptr_t pTemp;
uintptr_t pointerAddr;
for (int i = 0; i < PointerLevel; i++)
{
if (i == 0)
{
ReadProcessMemory(hProcHandle, (LPCVOID)pointer, &pTemp, sizeof(pTemp), NULL);
}
pointerAddr = pTemp + Offsets[i];
ReadProcessMemory(hProcHandle, (LPCVOID)pointerAddr, &pTemp, sizeof(pTemp), NULL);
}
return pointerAddr;
}
I would highly recommend watching some Youtube tutorials to see how it's done, much better explained in video format.

Receive messages only from a specific DDS topic instance?

I'm using OpenDDS v3.6, and trying to send a message to a specific DDS peer, one of many. In the IDL, the message structure looks like the following:
module Test
{
#pragma DCPS_DATA_TYPE "Test::MyMessage"
#pragma DCPS_DATA_KEY "Test::MyMessage dest_id"
struct MyMessage {
short dest_id;
string txt;
};
};
My understanding is that because the data key is unique, this is a new instance of the topic being written to, and any further msgs written w/ the same data key send to this specific instance of the topic. My send code is as follows:
DDS::ReturnCode_t ret;
Test::MyMessage msg;
// populate msg
msg.dest_id = n;
DDS::InstanceHandle_t handle;
handle = msg_writer->register_instance(msg);
ret = msg_writer->write(msg, handle);
So now I need to figure out how to get the receiving peer to read only from this topic instance and not receive all the other messages being sent to other peers. I started with the following, but not sure how to properly select a specific topic instance.
DDS::InstanceHandle_t instance;
status = msg_dr->take_next_instance(spec, si, 1, DDS::ANY_SAMPLE_STATE,
DDS::ANY_VIEW_STATE, DDS::ANY_INSTANCE_STATE);
Any help much appreciated.
The easiest way to achieve what you are looking for is by using a ContentFilteredTopic. This class is a specialization of the TopicDescription class and allows you to specify an expression (like a SQL WHERE-clause) of the samples that you are interested in.
Suppose you want your DataReader to only receive samples with dest_id equal to 42, then the corresponding code for creating the ContentFilteredTopic would look something like
DDS::ContentFilteredTopic_var cft =
participant->create_contentfilteredtopic("MyTopic-Filtered",
topic,
"dest_id = 42",
StringSeq());
From there on, you create your DataReader using cft as the parameter for the TopicDescription. The resulting reader will look like a regular DataReader, except that it only receives the desired samples and nothing else. Since the field dest_id happens to be the field that identifies the instance, the end result is that you will only have one instance in your DataReader.
You can check out the DDS specification (section 7.1.2.3.3) or OpenDDS Developer's Guide (section 5.2) for more details.

recvfrom() get the wrong source address

when i recvfrom(), the received message is correct, but the source address is totally a mess,
why is that happening?
char traid_messageR[MAXDATASIZE];
socklen_t addlen;
struct sockaddr_in source_addr;
if((numbytes=recvfrom(udp_sockfd, traid_messageR, 256, 0, (struct sockaddr*)&source_addr, &addlen)) == -1)
{
perror("recvfrom");
exit(1);
}
the result is like this:
(gdb) print source_addr
$1 = {sin_family = 61428, sin_port = 42, sin_addr = {s_addr = 49809},
sin_zero = "\234\352\377\277\310\352\377\277"}
the 49809 looks like a port number, but it is the port number of this receiver...does any one have idea why is this?thanks a lot
oh, another thing, i used this in a select() loop, IF_ISSET(und_socked,%fds),then exceute the above code, does this affect?
you didn't assign value to addlen
addlen = sizeof(source_addr)
UPDATE: refer to http://pubs.opengroup.org/onlinepubs/7908799/xns/recvfrom.html
The manual says
address_len Specifies the length of the sockaddr structure pointed
to
by the address argument. .....
If the address argument is not a null pointer and the protocol provides the source address of messages, the source address of the
received message is stored in the sockaddr structure pointed to by the
address argument, and the length of this address is stored in the
object pointed to by the address_len argument.
I found it explained better here:
In this case, addrlen is a value-
result argument. Before the call, it should be initialized to the
size of the buffer associated with src_addr. Upon return, addrlen is
updated to contain the actual size of the source address.
http://man7.org/linux/man-pages/man2/recv.2.html

Linux module: being notified about task creation and destruction

for Mach kernel API emulation on Linux, I need for my kernel module to get called when a task has been just created or is being terminated.
In my kernel module, this could most nicely be done via Linux Security Modules, but a couple of years ago, they prevented external modules from acting as a LSM by unexporting the needed symbols.
The only other way I could find was to make my module act like a rootkit. Find the syscall table and hook it in there.
Patching the kernel is out of the question. I need my app to be installed easily. Is there any other way?
You can use Kprobes, which enables you to dynamically hook into code in the kernel. You will need to find the right function among the ones involves in creating and destroying processes that give you the information you need. For instance, for tasks created, do_fork() in fork.c would be a good place to start. For tasks destroyed, do_exit. You would want to write a retprobe, which is a kind of kprobe that additionally gives you control at the end of the execution of the function, before it returns. The reason you want control before the function returns is to check if it succeeded in creating the process by checking the return value. If there was an error, then the function will return a negative value or in some cases possibly 0.
You would do this by creating a kretprobe struct:
static struct kretprobe do_fork_probe = {
.entry_handler = (kprobe_opcode_t *) my_do_fork_entry,
.handler = (kprobe_opcode_t *) my_do_fork_ret,
.maxactive = 20,
.data_size = sizeof(struct do_fork_ctx)
};
my_do_fork_entry gets executed when control enters the hooked function, and my_do_fork_ret gets executed just before it returns. You would hook it in as follows:
do_fork_probe.kp.addr =
(kprobe_opcode_t *) kallsyms_lookup_name("do_fork");
if ((ret = register_kretprobe(&do_fork_probe)) <0) {
// handle error
}
In the implementation of your hooks, it's a bit unwieldy to get the arguments and return value. You get these via the saved registers pt_regs data structure. Let's look at the return hook, where on x86 you get the return value via regs->ax.
static int my_do_fork_ret(struct kretprobe_instance *ri, struct pt_regs *regs)
{
struct do_fork_ctx *ctx = (struct do_fork_ctx *) ri->data;
int ret = regs->ax; // This is on x86
if (ret > 0) {
// It's not an error, probably a valid process
}
}
In the entry point, you can get access to the arguments via the registers. e.g. on x86, regs->di is the first argument, regs->si is the second etc. You can google to get the full list. Note that you shouldn't rely on these registers for the arguments in the return hook as the registers may have been overwritten for other computations.
You will surely have to jump many hoops in getting this working, but hopefully this note should set you off in the right direction.

Resources