Linux Project

Linux Project
中央大學資工系 碩士二年級
江瑞敏
Outline
How to compile linux kernel
How to add a new system call
Some Projects Example and Way to Solve it
System Call Hooking by Module
Project about Memory
Project about Process
Download Link
wget 
https://kernel.org/pub/linux/kernel/linux-2.6.18.tar.bz2
tar xvf linux-2.6.18.tar.bz2
The Beginning of everything
Compile Linux Kernel
It is Hard?
No, If you understand the concept
The Basic Process
0. make mrproper
1. make oldconfig
2. make –j[n]
3. make modules_install
4. make install
5. reboot
Do You Know What It Means?
make mrproer
Clean up the environment
Will Remove almost everything, except….
make clean
Almost the same as make mrproper.
make oldconfig
Use the configuration file the current kernel is
using.
Some other alternative options.
Make menuconfig
Is config File Important?
Config file
Determine which kind of kernel you are
compiling
Determine which modules you want the
kernel to compile.
Misconfiguration will lead to kernel crash.
make –j[n]
Compile the whole source code according to
your configuration
make modules_install
Install the modules into the necessary folder.
/lib/modules/`uname –r`/
make install
Install the image into the boot directory.
Sometimes, update grub is necessary.
What Is System Call
It’s a Bridge
Between
User
Device
Device
Device
Device
Why System Call
Pop Quiz :
Write A Program To Print “Hello World”
What You May Write
What Actually Happened ….
User Application
Kernel Code
System
Call
libc.so
Printf
Device Driver
IO Device
What If There Is No System Call
Everything Will Be
x86 instruction in and out
Let’s Focus On …
User Application
Kernel Code
System
Call
libc.so
Printf
Device Driver
IO Device
Magic int 0x80
Before We Talk Further,
Let’s Talk About X86 Architecture
X86 Architecture Is Interrupt Driven
CPU
8259 PIC
Kernel
Device
Device
Device
User Application
Device
Device Driver
How The CPU Find The Address of The
Device Driver Code
Callback Mechanism
CPU
8259 PIC
Device
Device
Device
Device
Device Driver
Device Driver
Device Driver
Device Driver
Interrupt Descriptor Table
…..
Kernel
Physical Device
How About System Call
Magic int 0x80
CPU
8259 PIC
Device
Device
Device
Device
Physical Device
syscall_table
…..
System
Call
Handler
System
Call
Handler
System
Call
Handler
int 0x80
CPU
cpu
CPU
GDT
TSS
cpu
CPU
GDT
Get TSS
TSS
cpu
CPU
IDT
 
Get IDT
0x80
ENTRY(system_call)
cpu
sys_call_table
CPU
IDT
Get IDT
0x80
ENTRY(system_call)
cpu
sys_call_table
CPU
IDT
Get IDT
0x80
ENTRY(system_call)
sys_call_table
cpu
How To Add A System Call
Add a System Call
1. cd $kernel_src
2. cd arch/i386/kernel/syscall_table.S
3.
….
.long sys_tee                   /* 315 */
.long sys_vmsplice
.long sys_move_pages
.long sys_project             /* 318 */
Kernel.org/pub/linux/kernel
Add a System Call
cd linux/include/asm-i386/unistd.h
#define __NR_vmsplice               316
#define __NR_move_pages         317
#define __NR_project                  318
#ifdef __KERNEL__
#define NR_syscalls 319
Add a System Call
cd linux/include/linux/syscalls.h
asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
        size_t len);
asmlinkage long sys_project( int i );
#endif
Add a System Call
cd linux/kernel
touch project.c
Makefile
obj-y = 
project.o
 sched.o fork.o
exec_domain.o panic.o printk.o profile.o
Add a System Call
Project.c
#include <linux/linkage.h>
#include <linux/kernel.h>
asmlinkage long sys_project( int i ){
        printk( "Success!! -- %d\n", i );
        return 0;
}
Add a System Call
Recompile linux kernel
Reboot
Create a new file “test.c”
#include<syscall.h>
int main(){
        syscall( 318, 2 );
        
return 0;
}
Add a System call
http://in1.csie.ncu.edu.tw/~hsufh/COURSES/F
ALL2007/syscall.html
About 64 bits
The Idea is the same
There are many online references
Therefore, I will not cover in this ppt.
System Call Hooking by Module
System Call Hooking
57
sys_call_table
正常的
execve
程式碼
Usermode 
程式呼叫
系統呼叫
NR_execve
System Call Hooking
58
sys_call_table
正常的
execve
程式碼
Usermode 
程式呼叫
系統呼叫
NR_execve
Hooking Code
System Call Hooking
59
sys_call_table
Usermode 
程式呼叫
系統呼叫
NR_execve
Hooking Code
正常的
execve
程式碼
Modified
execve
Source code links
http://pastebin.com/rShUxvB5
http://pastebin.com/KEJxgLGq
Project about Memory
Level 1:
Dump the virtual address of a process
Some Question U may Ask
Where to Start?
Maybe Add a New System Call
1. How to find the process you want?
Process List
task_struct
for_each_process()
If u pay attention in class, these two are not
stranger. 
2. How about Virtual Address that is
being used by the current process?
The Data Structure
mm_struct
vm_area_struct
lxr.linux.no
How it looks like
 
The rest is some basic programming
skill 
Too easy,
Let’s make it a little bit harder
Level 2:
Dump the physical frame that is
associate with the virtual address.
New Problem, New question
How to transfer Virtual Address to
Physical Address?
Some Reminder and Hints
Some Reminder and Hints
Where is CR3?
 
Now We Have CR3,
Then?
Calculate By Yourself
or
Something Smarter
follow_page()
Push Yourself More
Level 3:
Log these information to a file
Ok,
let’s type
dmesg || grep “myproject” >> log.txt
Dude
Are you…
…. From Kernel of course
Can We Do That???
How to write file in User Mode
fd = open(filename, “w”);
write(ptr, string, strlen(string));
close(fd);
How about Kernel Mode
open -> do_sys_open
Write -> sys_write()
Close -> sys_close()
Is that all?
The magic __user
It tell kernel that the parameter should
pass from user mode
It’s a protection mechanism
Final Step About this Project
Level 4:
Modify The PTE r/w flag
from read/write to read
http://in1.csie.ncu.edu.tw/~hsufh/COURSES/FAL
L2012/linux_project1.html
Structures of Page Directories And
Page Tables Entries
Wow, Looks Simple :D
Basic Idea
1. loop through the translation table of a
process according to the virtual address.
2. After finding the pte, change the read/write
flag
3. Done
pte_wrprotect()
Code Implement
for
(loop_count = addr; loop_count < end; loop_count+=PAGE_SIZE){
        pgd = pgd_offset(mm, loop_count);
        
if
 (pgd_none(*pgd)){
            printk("pgd none happened\n");
            
continue
;
        }
        pud = pud_offset(pgd, loop_count);
        pmd = pmd_offset(pud, loop_count);
        pte = pte_offset_map_lock(mm, pmd, loop_count, &ptl);
if
(operation == 1){
            
*pte = pte_mkwrite(*pte);
        } 
else
{
            
*pte = pte_wrprotect(*pte);
        }
Code Implement(Cont. )
Result
Result
What!?
Use Printk to Verify
Printk Tell Us Two Things
1. we have change the pte r/w flag
2. only one entry being change
back, other didn’t in most cases.
Magic Happened ?
Now,
Imagine you are CPU
What will happened when
some process try to access a read
only area
Page Fault Happened
The Question Becomes,
How Linux Handle Page Fault
U might Ask,
What is Page Fault
From CPU point of view
1.  present flag of pgd or pte is clear.
2. code running in user mode attempts to write to a
read only page.
More detailed check intel programmer manual.
From Kernel Point of View
1. present flag is clear:
A. Access the first time.
B. Page is being swap out.
2. write to a read only page:
A. is a process really write to a read only page
B. is a page-fault optimization such as copy on write.
How Does Linux Kernel Determine
These Kind of Difference
Well, First….
And This
Then This
 
What The FxxK…….
This Time Let’s Look Closer
 
 
Now We Know An Important Thing
Linux Kernel Will Compare The
vm_flag
Some Useful Knowledge
How Linux Implement COW
Cow??
Moo ?
 
1. COW refer to copy on write
2. google and wiki are your friend
3. how linux implement copy on write.
A. 
pte r/w flag disable
B. 
vm_flag & VM_WRITE == true
 
Our project accidently match
the above conditions!
1. same page table entry of parent and child
process point to the same pfn
2. set r/w flag of both pte to read only
3. when page fault happened, page fault handler
will check the vm_flag of the current virtual
address.
4. if vm_flag has VM_WRITE, page fault handler
will refer this situation as a COW condition.
5. assign a new pfn with r/w flag enable if there
are two pte point to it.
Copy on Write linux implement
parent
 
child
Task_struct
 
Task_struct
pte
 
pte
Physical address
pgd
 
pgd
A New Idea of The Project
1. Change PTE r/w flag as we just did
2. Change the vm_flag as well
down_write(&current->mm->mmap_sem);
vma = find_vma(mm, addr);
vm_start = vma->vm_start;
vm_end = vma->vm_end;
mask = VM_READ|VM_WRITE|VM_EXEC|VM_SHARED;
new_flags = VM_READ;
old_flags = vma->vm_flags;
if
(old_flags&VM_WRITE){
            
old_flags &= ~(VM_WRITE);
            new_flags |= old_flags;
} 
else
{
            new_flags |= old_flags;
    prot = protection_map[new_flags & mask];
    
vma->vm_flags = new_flags;
    
vma->vm_page_prot = prot;
    up_write(&current->mm->mmap_sem);
    addr &= PAGE_MASK;    
    change_pte(addr, end, operation);
Code Implementation
Result
Where is the “press enter
to continue” ?
It’s time to use GDB
Set a break point before syscall happened
Seems like this time printf cause the error
Here is the problem.
Think Slowly
Calling printf will need to push some
parameters
Recall From The Last Code
we have changed vm_flag for the whole
vm_area_struct which means the 
entire block
of linear address
.
Address of the array 
is not always align to 4kb
.
Consider The following Conditions
Start address align
End address align
 
Start Address Align
End Address Not Align
Start Address Not Align
End Address Align
Start addr
End addr
Total need 
3 pages
Area problem may occur
low
high
Test array
 
Start Address Not Align
End Address Not Align
Start addr
End addr
Area problem may occur
Area problem may occur
Total need 
4 pages
Test_array
low
high
 
Our case
 
The parameter is right here
Since the page is RO.
low
high
Assembly code:
…..
Call syscall;
Push $string;
Call printf;
Rewrite the user mode program. This time use
malloc instead of local variable.(Heap instead
of stack)
Char *test_array;
Test_array = (char *)malloc(ARRAY_SIZE)
Verify Our Thoughts (Test case 1)
Test Case 1 Result
 
Char test1[0x2000];
Char test_array[ARRAY_SIZE];
Char test2[0x2000];
This can also bypass the conditions that I just
mentioned.
Verify Our Thoughts (Test case 2)
Test Case 2 Result
Also work~~
 
1. basically, the idea is the same.
A. change vm_flag
B. change pte r/w flag
2. Some hints:
A. Strongly recommend reading Text Book
Chapter 8: Memory Management
Chapter 9: Process Address Space
B. code to change vma_flag is in 
mprotect_fixup()
.
C. the code to loop through the translation table starts from
    
change_protection(….)
    -> change_pud(….)
    -> change_pmd(…..)
    -> change_pte_range(…..)
How About Mprotect.c
Full Source
Level 1 and 2 :
http://pastebin.com/wEVLaQyg
Level 3:
http://pastebin.com/HFW8WTN5
Slide Note
Embed
Share

Process of compiling the Linux kernel and working on various projects like adding new system calls, memory management, and process handling. Understand the essential steps and commands involved in kernel compilation. Dive into the significance of configuration files and the potential risks of misconfigurations. Discover efficient project solutions and system call hooking techniques. Get insights into the basics and complexities of Linux kernel development.

  • Linux
  • Kernel Compilation
  • System Calls
  • Project Development
  • Memory Management

Uploaded on Feb 22, 2025 | 0 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.

E N D

Presentation Transcript


  1. Linux Project

  2. Outline How to compile linux kernel How to add a new system call Some Projects Example and Way to Solve it System Call Hooking by Module Project about Memory Project about Process

  3. Download Link wget https://kernel.org/pub/linux/kernel/linux-2.6.18.tar.bz2 tar xvf linux-2.6.18.tar.bz2

  4. The Beginning of everything

  5. Compile Linux Kernel

  6. It is Hard?

  7. No, If you understand the concept

  8. The Basic Process 0. make mrproper 1. make oldconfig 2. make j[n] 3. make modules_install 4. make install 5. reboot

  9. Do You Know What It Means?

  10. make mrproer Clean up the environment Will Remove almost everything, except .

  11. make clean Almost the same as make mrproper.

  12. make oldconfig Use the configuration file the current kernel is using. Some other alternative options. Make menuconfig

  13. Is config File Important?

  14. Config file Determine which kind of kernel you are compiling Determine which modules you want the kernel to compile. Misconfiguration will lead to kernel crash.

  15. make j[n] Compile the whole source code according to your configuration

  16. make modules_install Install the modules into the necessary folder. /lib/modules/`uname r`/

  17. make install Install the image into the boot directory. Sometimes, update grub is necessary.

  18. What Is System Call

  19. Its a Bridge

  20. Between Device Device User Device Device

  21. Why System Call

  22. Pop Quiz : Write A Program To Print Hello World

  23. What You May Write

  24. What Actually Happened .

  25. User Application Printf libc.so System Call Kernel Code Device Driver IO Device

  26. What If There Is No System Call

  27. Everything Will Be x86 instruction in and out

  28. Lets Focus On User Application Printf libc.so System Call Kernel Code Device Driver IO Device

  29. Magic int 0x80

  30. Before We Talk Further, Let s Talk About X86 Architecture

  31. X86 Architecture Is Interrupt Driven

  32. User Application Kernel Device Driver CPU 8259 PIC Device Device Device Device

  33. How The CPU Find The Address of The Device Driver Code

  34. Callback Mechanism

  35. Kernel Device Driver Interrupt Descriptor Table Device Driver .. Device Driver Device Driver CPU 8259 PIC Device Device Device Device Physical Device

  36. How About System Call

  37. Magic int 0x80

  38. System Call Handler Interrupt Descriptor Table syscall_table System Call Handler .. .. 0x80 .. System Call Handler CPU 8259 PIC int 0x80 Device Device Device Device Physical Device

  39. cpu cs ds ss esp eip int 0x80 User Application CPU Stack Kernel

  40. cpu cs ds ss esp eip int 0x80 User Application CPU Get TSS GDT Stack TSS

  41. cpu cs ds ss esp eip int 0x80 User Application CPU Get TSS GDT Stack TSS

  42. cpu cs ds ss esp eip int 0x80 User Application CPU Get IDT IDT ENTRY(system_call) Stack 0x80 sys_call_table

  43. cpu cs ds ss esp eip int 0x80 User Application CPU Get IDT IDT ENTRY(system_call) Stack 0x80 sys_call_table

  44. cpu cs ds ss esp eip int 0x80 User Application CPU Get IDT IDT ENTRY(system_call) Stack ss esp eflags cs eip 0x80 sys_call_table

  45. How To Add A System Call

  46. Add a System Call 1. cd $kernel_src 2. cd arch/i386/kernel/syscall_table.S 3. . .long sys_tee .long sys_vmsplice .long sys_move_pages .long sys_project Kernel.org/pub/linux/kernel /* 315 */ /* 318 */

  47. Add a System Call cd linux/include/asm-i386/unistd.h #define __NR_vmsplice #define __NR_move_pages #define __NR_project 316 317 318 #ifdef __KERNEL__ #define NR_syscalls 319

  48. Add a System Call cd linux/include/linux/syscalls.h asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, size_t len); asmlinkage long sys_project( int i ); #endif

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#