或者直接搜索:
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/kernel.h>
static int __init lkm_init(void)
{
int i, j;
unsigned char *ptr;
ptr = (unsigned char *)(0xffffffff816b4fc9 - 0x16 + 0xf);
for (i = 0; i < 20; i ++) {
if( ((unsigned char)ptr[i] == 0xff) && ((unsigned char)ptr[i + 1] == 0x14) && ((unsigned char)ptr[i +2] == 0xc5) ){
printk("0x%x ", *(unsigned int *)(ptr+i+3));
break;
}
}
return 0;
}
static void __exit lkm_exit(void)
{
}
module_init(lkm_init);
module_exit(lkm_exit);
MODULE_LICENSE(“GPL”);
insmod sys_call_table.ko
dmesg -c
[ 280.502659] 0x816beee0
因此sys_call_table的地址是0xffffffff816beee0。
三、根据MSR_LSTAR寄存器
我们来看一下内核的启动过程:
start_kernel()
–>trap_init()
–>cpu_init()
–>syscall_init()
#define MSR_STAR 0xc0000081 /* legacy mode SYSCALL target */
#define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */
#define MSR_CSTAR 0xc0000083 /* compat mode SYSCALL target */
| Register
Address | Architectural MSR Name / Bit Fields (Former MSR Name) | MSR/Bit Description |
---|---|---|
C000_0081H | IA32_STAR | System Call Target Address (R/W) |
C000_0082H | IA32_LSTAR | IA-32e Mode System Call Target Address (R/W) Target RIP for the called procedure when SYSCALL is executed in 64-bit mode. |
C000_0083H | IA32_CSTAR | IA-32e Mode System Call Target Address (R/W) Not used, as the SYSCALL instruction is not recognized in compatibility mode. |
我们主要看MSR_LSTAR寄存器:
IA32_LSTAR 是 IA-32e 模式下的系统调用目标地址寄存器,用于存储在 64 位模式下执行 SYSCALL 指令时被调用过程的目标 RIP(指令指针)。
当在 64 位模式下执行 SYSCALL 指令时,系统将从 IA32_LSTAR 寄存器中加载 RIP 的值,以跳转至相应的系统调用处理程序。
为了使内核接收传入的系统调用,它必须通过将其地址写入IA32_LSTAR MSR寄存器 来注册将在发生系统调用时执行的代码的地址。
/* May not be marked __init: used by software suspend */
void syscall_init(void)
{
/*
* LSTAR and STAR live in a bit strange symbiosis.
* They both write to the same internal register. STAR allows to
* set CS/DS but only a 32bit target. LSTAR sets the 64bit rip.
*/
wrmsrl(MSR_STAR, ((u64)__USER32_CS)<<48 | ((u64)__KERNEL_CS)<<32);
wrmsrl(MSR_LSTAR, system_call);
wrmsrl(MSR_CSTAR, ignore_sysret);
…
/* Flags to clear on syscall */
wrmsrl(MSR_SYSCALL_MASK,
X86_EFLAGS_TF|X86_EFLAGS_DF|X86_EFLAGS_IF|
X86_EFLAGS_IOPL|X86_EFLAGS_AC);
}
这行代码把system_call入口地址存入到MSR_LSTAR寄存器。syscall指令会把该地址加载到到%rip寄存器,从该地址开始执行。
syscall指令:
SYSCALL 指令用于在特权级别 0(内核模式)下调用操作系统的系统调用处理程序。它通过从 IA32_LSTAR MSR 寄存器加载 RIP(同时将 SYSCALL 指令后面的指令地址保存在 RCX 中)来实现这一功能。IA32_LSTAR MSR 寄存器的值是一个规范地址(canonical address),通过 WRMSR 指令确保其始终包含一个规范地址。
SYSCALL 指令:RIP = IA32_LSTAR MSR 寄存器 = system_call
过程如下:
特别说明一下,因为初始化时,掩码中包含中断标志位X86_EFLAGS_IF,所以syscall指令执行时,中断是禁止的。
我们可以看到在syscall_init中将 system_call 的地址写入了 MSR_LSTAR 寄存器:
wrmsrl(MSR_LSTAR, system_call);
那么我们读取MSR_LSTAR寄存器就可以获取到system_call的地址,进入获取到sys_call_table的地址。
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/kernel.h>
static int __init lkm_init(void)
{
unsigned long msr_lstar;
rdmsrl(MSR_LSTAR, msr_lstar);
printk(“MSR_LSTAR = %lx\n”, msr_lstar);
return 0;
}
static void __exit lkm_exit(void)
{
}
module_init(lkm_init);
module_exit(lkm_exit);
MODULE_LICENSE(“GPL”);
]# cat /proc/kallsyms | grep ‘<system_call>’
ffffffff816b4f50 T system_call
insmod get_msr.ko
dmesg -c
[ 1474.209016] MSR_LSTAR = ffffffff816b4f50
获取到了system_call的地址那么解析其后面的字节便可以找到sys_call_table的地址。
完整代码:
#include <linux/module.h>
#include <linux/kernel.h>
void *memmem(const void *haystack, size_t haystack_size, const void *needle, size_t needle_size )
{
char *p;
for (p = (char *)haystack; p <= ((char *)haystack - needle_size + haystack_size); p++ )
if (memcmp(p, needle, needle_size) == 0 )
return (void *)p;
return NULL;
}
unsigned long *find_sys_call_table ( void )
{
char **p;
unsigned long sct_off = 0;
unsigned char code[512];
rdmsrl(MSR_LSTAR, sct_off);
memcpy(code, (void *)sct_off, sizeof(code));
p = (char **)memmem(code, sizeof(code), “\xff\x14\xc5”, 3);
if §
{
unsigned long *sct = *(unsigned long **)((char *)p + 3);
// Stupid compiler doesn’t want to do bitwise math on pointers
sct = (unsigned long *)(((unsigned long)sct & 0xffffffff) | 0xffffffff00000000);
return sct;
}
else
return NULL;
}
static int __init lkm_init(void)
{
unsigned long *sys_call_table = find_sys_call_table();
printk(“The sys_call_table address is:%lx\n”,(unsigned long)sys_call_table);
return 0;
}
static void __exit lkm_exit(void)
{
}
module_init(init_get_sys_call_table);
module_exit(exit_get_sys_call_table);
MODULE_LICENSE(“GPL”);
cat /proc/kallsyms | grep ‘<sys_call_table>’
ffffffff816beee0 R sys_call_table
insmod sys_call_table.ko
dmesg -c
[ 2363.360239] The sys_call_table address is:0xffffffff816beee0
四、使用sys_close
// linux-3.10/fs/open.c
/*
* Careful here! We test whether the file pointer is NULL before
* releasing the fd. This ensures that one clone task can’t release
* an fd while another clone is opening it.
*/
SYSCALL_DEFINE1(close, unsigned int, fd)
{
int retval = __close_fd(current->files, fd);
/* can’t restart close syscall because file table entry was cleared */
if (unlikely(retval == -ERESTARTSYS ||
retval == -ERESTARTNOINTR ||
retval == -ERESTARTNOHAND ||
retval == -ERESTART_RESTARTBLOCK))
retval = -EINTR;
return retval;
}
EXPORT_SYMBOL(sys_close);
EXPORT_SYMBOL(sys_close);
系统调用函数(sys_close)在内核中是导出的,因此可以直接获取其地址。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注网络安全获取)
还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!
王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。
对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!
【完整版领取方式在文末!!】
93道网络安全面试题
内容实在太多,不一一截图了
黑客学习资源推荐
最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
😝朋友们如果有需要的话,可以联系领取~
1️⃣零基础入门
① 学习路线
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
② 路线对应学习视频
同时每个成长路线对应的板块都有配套的视频提供:
2️⃣视频配套工具&国内外网安书籍、文档
① 工具
② 视频
③ 书籍
资源较为敏感,未展示全面,需要的最下面获取
② 简历模板
因篇幅有限,资料较为敏感仅展示部分资料,添加上方即可获取👆
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
c485f8407a99619f9c5b5.png#pic_center)
② 简历模板
因篇幅有限,资料较为敏感仅展示部分资料,添加上方即可获取👆
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-DEM7QSkM-1712506967919)]