How to "talk" with USB device via my module? - driver

I've written my module for gamepad that plugged by USB. I've already checked that my installed module detects my device successfully and even calls "probe" method:
static struct usb_driver driver =
{
.name = "Driver#1",
.id_table = table,
.probe = probe,
.disconnect = disconnect,
};
I have also written special urb function, that should "talk" with my device
usb_fill_int_urb(j->irq_in, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), //!
j->idata, 32, irq_hh,
j, ep_irq_in->bInterval);
But I cannot understand how to initialize action of irq_in. I presume that I need to press something and some information should be written in j->idata. I also did
usb_submit_urb(j->irq_in, GFP_KERNEL);
But nothing happens! Why?
My probe function:
static void irq_hh(struct urb *urb)
{
struct devicec *j = urb->context;/*В какую структура из всех процессов дб заполнена после приёма данных???*/
char *data = j->idata;
printk(KERN_INFO "irq_hh: %s", data);
}
static int probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *udev; //!
struct usb_endpoint_descriptor *ep_irq_in;
int ep_irq_in_idx, error;
printk(KERN_INFO "probe...%X",id->idVendor);
j = kzalloc(sizeof(struct devicec), GFP_KERNEL);
udev = interface_to_usbdev(intf);
j->irq_in = usb_alloc_urb(0, GFP_KERNEL);
//--------------------------------------
j->udev = udev;
j->intf = intf;
//--------------------------------------
usb_make_path(udev, j->phys, sizeof(j->phys));
strlcat(j->phys, "/input101", sizeof(j->phys));
printk(KERN_INFO "%s",j->phys);
ep_irq_in_idx = 0;
ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc;
usb_fill_int_urb(j->irq_in, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), //!
j->idata, 32, irq_hh,
j, ep_irq_in->bInterval);
j->irq_in->transfer_dma = j->idata_dma;
j->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
error = usb_submit_urb(j->irq_in, GFP_KERNEL);
printk(KERN_INFO "%d",error);
return 0;
}

Related

trouble with pmi handle on windows 7

I am trying to set up performance monitorint interrupt on counter overflow to collect some information. For this I created driver. I skip some part of code that are irrelevant.
driver.c
extern VOID EnableReadPmc();
extern VOID PmiHandle();
extern VOID GetIdt(IDT_INFO *idt);
extern ULONG64 GetCs();
#pragma pack(2)
typedef struct {
USHORT Limit;
ULONG64 Base;
}IDT_INFO;
#pragma pack()
typedef struct _entry {
ULONG64 Low;
ULONG64 High;
} entry;
PHYSICAL_ADDRESS lvt_perf_count_reg = {0xfee00340, 0x00000000};
PVOID map_lvt_perf_count_reg = NULL;
PHYSICAL_ADDRESS eoi_register = {0xfee000b0, 0x00000000};
PVOID map_eoi_register = NULL;
NTSTATUS IoCtlDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) {
ULONG32 set_lvt_perf_count_reg = 0x000000ee;
//idt
IDT_INFO idtr;
entry *idt = NULL;
entry tmp_gate;
ULONG64 func;
ULONG64 seg;
ULONG64 int_setting;
//ovf status value
ULONG64 ovf_status;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_INTERRUPT_SETTING_UP:
//disable pmc and clear ovf
WriteMsr(IA32_PERF_GLOBAL_CTRL, 0x00);
WriteMsr(IA32_FIXED_CTR_CTRL, 0x00);
ovf_status = ReadMsr(IA32_PERF_GLOBAL_STATUS);
WriteMsr(IA32_PERF_GLOBAL_OVF_CTRL, ovf_status);
//setting up lvt entry
map_lvt_perf_count_reg = MmMapIoSpace(lvt_perf_count_reg, 4, MmNonCached);
*(PULONG32)map_lvt_perf_count_reg = set_lvt_perf_count_reg;
map_eoi_register = MmMapIoSpace(eoi_register, 4, MmNonCached);
//setting up idt handler
idtr.Limit = 0;
idtr.Base = 0;
GetIdt(&idtr);
idt = idtr.Base;
tmp_gate.Low = 0;
tmp_gate.High = 0;
func = 0;
seg = 0;
int_setting = 0x8e00;
//p = 1 dpl = 0 type(interrupt gate) = 1110 ist = 0
seg = GetCs();
func = (ULONG64)PmiHandle;
tmp_gate.Low = func & 0x0ffff;
tmp_gate.Low = seg << 16 | tmp_gate.Low;
tmp_gate.Low = int_setting << 32 | tmp_gate.Low;
tmp_gate.Low = ((func & 0x0ffff0000) << 32) | tmp_gate.Low;
tmp_gate.High = (func & 0xffffffff00000000) >> 32;
idt[238] = tmp_gate;
MmUnmapIoSpace(map_lvt_perf_count_reg, 4);
map_lvt_perf_count_reg = NULL;
pIrp->IoStatus.Information = 0;
break;
default:
DbgPrint("Error in switch");
break;
}
status = pIrp->IoStatus.Status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
pmihandle.asm
public PmiHandle
extern Handle : proc
.code
PmiHandle:
call Handle
add rsp, 8
iretq
end
handle.c
#define IA32_PERF_GLOBAL_CTRL 0x38f
#define IA32_PERF_GLOBAL_STATUS 0x38e
#define IA32_PERF_GLOBAL_OVF_CTRL 0x390
extern ULONG64 ovf_status_handle;
extern PVOID map_eoi_register;
VOID Handle() {
WriteMsr(IA32_PERF_GLOBAL_CTRL, 0x00);
ovf_status_handle = ReadMsr(IA32_PERF_GLOBAL_STATUS);
WriteMsr(IA32_PERF_GLOBAL_OVF_CTRL, ovf_status_handle);
DbgPrint("INTERRUPT_INTERRUPT_INTERRUPT");
if (map_eoi_register != NULL)
*(PULONG32)map_eoi_register = 0x0;
else
DbgPrint("EOI failed");
}
main.c application with which I turn on counters
#include <stdio.h>
#include "include/msr_sampling.h"
#define FILE_DEVICE_MSR 0x8000
#define IOCTL_INTERRUPT_SETTING_UP CTL_CODE(FILE_DEVICE_MSR, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_FILE_TEST CTL_CODE(FILE_DEVICE_MSR, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
int main() {
SetProcForMsrCtr(); //set affinity mask for first proc
DriverOpen();
EnableReadPmc(); //enable __readpmc instruction
DWORD numberData = -1;
DeviceIoControl(hFile, IOCTL_INTERRUPT_SETTING_UP, NULL, 0, NULL, 0, &numberData, NULL);
ULONG64 value;
value = 0x000000000000000b;
WriteMsr(IA32_FIXED_CTR_CTRL, value);
value = 0xfffffffff000; //old value ffffffffc000
printf("%llu\n", __readpmc((1 << 30)));
WriteMsr(0x309, value);
printf("%llx\n", __readpmc((1 << 30)));
printf("=================================================\n");
ReadMsr(IA32_PERF_GLOBAL_CTRL, &value);
printf("%llX\n", value);
value = 0x0000000100000000;
WriteMsr(IA32_PERF_GLOBAL_CTRL, value);
printf("counter value: %llX\n", __readpmc((1 << 30)));
DriverClose();
system("pause");
return 0;
}
When I launch application my computer froze(does not respond to mouse movement and press key).
But if I generate interrupt with using assembly instuction INT it is OK.
I checked IDT and LVT entry via WinDbg they are correct.
What could be the problem?
Some informantion:
My processor is Intel Core i5-3210M. OS windows 7 x64. I do this on laptop.

What does "unconnected:sendto() " return value mean?

The LuaSocket documentation says:
unconnected:sendto(datagram, ip, port)
If successful, the method returns 1. In case of error, the method
returns nil followed by an error message.
But I get a value of 4. What does return value of 4 means?
My code is here:
local socket = require("socket")
udp = socket.udp()
udp:setsockname("*", 8080)
local msg = "Test"
m=assert(udp:sendto( msg, "228.192.1.1", 8080))
print(m)
Looking closely at the source inside udp.c for sendo method
static int meth_sendto(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1);
size_t count, sent = 0;
const char *data = luaL_checklstring(L, 2, &count);
const char *ip = luaL_checkstring(L, 3);
const char *port = luaL_checkstring(L, 4);
p_timeout tm = &udp->tm;
int err;
struct addrinfo aihint;
struct addrinfo *ai;
memset(&aihint, 0, sizeof(aihint));
aihint.ai_family = udp->family;
aihint.ai_socktype = SOCK_DGRAM;
aihint.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
err = getaddrinfo(ip, port, &aihint, &ai);
if (err) {
lua_pushnil(L);
lua_pushstring(L, gai_strerror(err));
return 2;
}
timeout_markstart(tm);
err = socket_sendto(&udp->sock, data, count, &sent, ai->ai_addr,
(socklen_t) ai->ai_addrlen, tm);
freeaddrinfo(ai);
if (err != IO_DONE) {
lua_pushnil(L);
lua_pushstring(L, udp_strerror(err));
return 2;
}
lua_pushnumber(L, (lua_Number) sent);
return 1;
}
Basically, the documentation's "returns 1" statement is wrong. The return 1 statement in the code means that the actual function returns one value, which is actually pushed into the stack:
lua_pushnumber(L, (lua_Number) sent);
where the variable sent was calculated just a few statements above (check socket_sendto call.
So, the returned 4 is exactly what #moteus commented: The number of bytes sent.
sendto returns the number of bytes sent.

dylib or executable export list

I am writing a plugins subsystem and one of the ideas is to iterate through a dylib (or at least current global scope) exported functions. I know there are other ways, just really want to give this one a try.
What I am wondering, is there a way to get a list of functions exported by a dylib or available in global scope through OS X and iOS API?
Thanks in advance!
You can use a command 'nm' for getting an information from a dynamic library.
See additionally system manual for this command on Mac.
If you are looking to do that from code, you could use this method.
std::vector<std::string> load_mach_o(std::string file_name)
{
/*
Parse the Mach-O structure to find all the exported symbols
Mach-O structure:
mach_header_64
cmd
...
cmd
data
...
data
*/
std::vector<std::string> methods;
off_t offset = sizeof(struct mach_header_64);
BYTE * bytes = load_bytes(file_name.c_str());
if (bytes == NULL)
{
return methods;
}
struct mach_header_64 *header = (struct mach_header_64 *)bytes;
//Get the load commands
struct load_command *cmd = (struct load_command *)(bytes + offset);
for (uint32_t i = 0U; i < header->ncmds; i++)
{
if (cmd->cmd == LC_SYMTAB)
{
struct symtab_command * symtab = (struct symtab_command *)cmd;
off_t string_start = 0;
const char* strings = (const char *)(bytes + symtab->stroff + 1);
for (uint32_t i = 0 ; i < symtab->strsize ; i++)
{
if (strings[i] == '\0')
{
i++;
size_t size = sizeof(char) * (i - string_start);
if (size == 1)
{
string_start = i+1;
continue;
}
methods.push_back(std::string((const char *)(strings + string_start)));
string_start = i+1;
}
}
}
offset += cmd->cmdsize;
//load next command
cmd = (struct load_command *)(bytes + offset);
}
free(bytes);
return methods;
}
This function read the file and parses the structure till mach-O strings section, then, parses each string and store it in a vector containing all the exposed functions.
Best regards.

Libnet11 build IPv6 packet manually

I am trying to use Libnet11 function:
int libnet_write_raw_ipv6 (libnet_t *l, u_int8_t *packet, u_int32_t size)
to inject IPv6 packet on network layer.
I had created IPv6 packet and captured it
with Wireshark. Wireshark reported:
malformed packet(wireshark says that next
header value in IPv6 is wrong and payload
size is too big in my opinion)
I hope, someone could help me with minimal code example,
showing how to manually build IPv6 packet (with ICMPv6
extension header) with libnet11 (libnet_write_raw_ipv6()).
I assume that the minimal code might look like this:
packet_len = 40 + 16; // 40B ~ IPv6 packet, 16B ~ ICMPv6 header
u_char *buf = NULL;
struct ip6_hdr *ip6 = NULL;
struct icmp6_hdr *icmp6 = NULL;
l = libnet_init();
if ( (buf = malloc(packet_len)) == NULL ) {
// error
}
// create IPv6 header
ip6 = (struct ip6_hdr *) buf;
ip6->ip6_flow = 0;
ip6->ip6_vfc = 6 << 4;
ip6->ip6_plen = 16; // ICMPv6 packet size
ip6->ip6_nxt = IPPROTO_ICMPV6; // 0x3a
ip6->ip6_hlim = 64;
memcpy(&(ip6->ip6_src), &src_addr, sizeof(struct in6_addr));
memcpy(&(ip6->ip6_dst), &dst_addr, sizeof(struct in6_addr));
// create ICMPv6 header
icmp6 = (struct icmp6_hdr *) (buf + 40); // 40B ~ IPv6 packet size
icmp6->icmp6_type = ICMP6_ECHO_REQUEST;
icmp6->icmp6_code = 0;
icmp6->icmp6_cksum= 0;
icmp6->icmp6_data32[0] = 0;
libnet_do_checksum(l, (u_int8_t *)buf, IPPROTO_ICMPV6, packet_len);
written = libnet_write_raw_ipv6(l, buf, packet_len);
if ( written != packet_len )
perror("Failed to send packet");
libnet_destroy(l);
free(buf);
I tried to find code examples but with no success.
Thank you in advance.
Martin
If you're using C++, then I'd recommend you libtins, a packet crafting a sniffing library. This short snippet does exactly what you want:
#include <tins/tins.h>
using namespace Tins;
void test(const IPv6Address &dst, const IPv6Address &src) {
PacketSender sender;
IPv6 ipv6 = IPv6(dst, src) / ICMPv6();
ipv6.hop_limit(64);
sender.send(ipv6);
}
int main() {
// now use it
test("f0ef:1234::1", "f000::1");
}
You can create it with raw sockets though. I also had to do something similar but couldn't find anything as a reference.
To do it with raw sockets, this link gives you a nice explanation

zError function call in zLib impacting performance

When using zlib 1.25 in an iOS project, I've noticed in my profiler (Instruments) that the function zError is being called repeatedly, and is occupying 50% of the overall inflate time.
Does anyone know why zError would be getting invoked like this? I don't call it anywhere in my own code, which is a pretty boilerplate inflate function, pasted below:
int UPNExtractorGZInflate(const void *src, int srcLen, void *dst, int dstLen) {
z_stream strm = {0};
strm.total_in = strm.avail_in = srcLen;
strm.total_out = strm.avail_out = dstLen;
strm.next_in = (Bytef *) src;
strm.next_out = (Bytef *) dst;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
int err = -1;
int ret = -1;
err = inflateInit2(&strm, (15 + 16)); //15 window bits, and the +16 tells zlib to decode gzip
if (err == Z_OK) {
err = inflate(&strm, Z_FINISH);
if (err == Z_STREAM_END) {
ret = strm.total_out;
}
else {
inflateEnd(&strm);
return err;
}
}
else {
inflateEnd(&strm);
return err;
}
inflateEnd(&strm);
return ret;
}
And here is the relevant profiler output (notice zError taking 50% of the overall inflate time):
zError isn't called by any zlib function. If you're not calling it, then your profiler is misidentifying the function taking that time.

Resources