1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
#ifndef _CURRENT_C_ /* -*- linux-c -*- */
#define _CURRENT_C_
#include "regs.h"
/** @file current.c
* @brief Functions to get the current state.
*/
/** @addtogroup current Current State
* Functions to get the current state.
* @{
*/
/** Get the current return address.
* Call from kprobes (not jprobes).
* @param regs The pt_regs saved by the kprobe.
* @return The return address saved in the stack pointer.
* @note i386 and x86_64 only so far.
*/
unsigned long _stp_ret_addr (struct pt_regs *regs)
{
#ifdef __x86_64__
unsigned long *ra = (unsigned long *)regs->rsp;
if (ra)
return *ra;
else
return 0;
#elif defined (__i386__)
return regs->esp;
#else
#error Unimplemented architecture
#endif
}
#ifdef __x86_64__
void _stp_sprint_regs(String str, struct pt_regs * regs)
{
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
unsigned int fsindex,gsindex;
unsigned int ds,cs,es;
_stp_sprintf(str,"RIP: %016lx\nRSP: %016lx EFLAGS: %08lx\n", regs->rip, regs->rsp, regs->eflags);
_stp_sprintf(str,"RAX: %016lx RBX: %016lx RCX: %016lx\n",
regs->rax, regs->rbx, regs->rcx);
_stp_sprintf(str,"RDX: %016lx RSI: %016lx RDI: %016lx\n",
regs->rdx, regs->rsi, regs->rdi);
_stp_sprintf(str,"RBP: %016lx R08: %016lx R09: %016lx\n",
regs->rbp, regs->r8, regs->r9);
_stp_sprintf(str,"R10: %016lx R11: %016lx R12: %016lx\n",
regs->r10, regs->r11, regs->r12);
_stp_sprintf(str,"R13: %016lx R14: %016lx R15: %016lx\n",
regs->r13, regs->r14, regs->r15);
asm("movl %%ds,%0" : "=r" (ds));
asm("movl %%cs,%0" : "=r" (cs));
asm("movl %%es,%0" : "=r" (es));
asm("movl %%fs,%0" : "=r" (fsindex));
asm("movl %%gs,%0" : "=r" (gsindex));
rdmsrl(MSR_FS_BASE, fs);
rdmsrl(MSR_GS_BASE, gs);
rdmsrl(MSR_KERNEL_GS_BASE, shadowgs);
asm("movq %%cr0, %0": "=r" (cr0));
asm("movq %%cr2, %0": "=r" (cr2));
asm("movq %%cr3, %0": "=r" (cr3));
asm("movq %%cr4, %0": "=r" (cr4));
_stp_sprintf(str,"FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
fs,fsindex,gs,gsindex,shadowgs);
_stp_sprintf(str,"CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0);
_stp_sprintf(str,"CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
}
#elif defined (__i386__)
/** Write the registers to a string.
* @param regs The pt_regs saved by the kprobe.
* @note i386 and x86_64 only so far.
*/
void _stp_sprint_regs(String str, struct pt_regs * regs)
{
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
_stp_sprintf (str, "EIP: %08lx\n",regs->eip);
_stp_sprintf (str, "ESP: %08lx\n",regs->esp);
_stp_sprintf (str, "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
regs->eax,regs->ebx,regs->ecx,regs->edx);
_stp_sprintf (str, "ESI: %08lx EDI: %08lx EBP: %08lx",
regs->esi, regs->edi, regs->ebp);
_stp_sprintf (str, " DS: %04x ES: %04x\n",
0xffff & regs->xds,0xffff & regs->xes);
__asm__("movl %%cr0, %0": "=r" (cr0));
__asm__("movl %%cr2, %0": "=r" (cr2));
__asm__("movl %%cr3, %0": "=r" (cr3));
/* This could fault if %cr4 does not exist */
__asm__("1: movl %%cr4, %0 \n"
"2: \n"
".section __ex_table,\"a\" \n"
".long 1b,2b \n"
".previous \n"
: "=r" (cr4): "0" (0));
_stp_sprintf (str, "CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
}
#endif
/** Print the registers.
* @param regs The pt_regs saved by the kprobe.
* @note i386 and x86_64 only so far.
*/
#define _stp_print_regs(regs) \
{ \
_stp_sprint_regs(_stp_stdout,regs); \
_stp_print_flush(); \
}
/** @} */
#endif /* _CURRENT_C_ */
|