如何在linux下閱讀源碼以及提取寫簡單demo
阿新 • • 發佈:2018-06-26
lse AD debian control %d aging sca view cmd //如何在linux下閱讀源碼以及提取寫demo
這裏以 ps 為例
用到的工具有 clion
先查看 ps 路徑
which
這裏以 ps 為例
用到的工具有 clion
先查看 ps 路徑
which
root@ubuntu:~# which ps
/bin/ps
root@ubuntu:~#
查看源碼包
dpkg
root@ubuntu:~# dpkg -S /bin/ps
procps: /bin/ps
root@ubuntu:~#
使用 apt-get 下載(這裏可能會報xxxxxxxx cannot be authenticated. 更新下就好 sudo apt-key update sudo apt-get update)
(它會下載很多東西 只關心源碼文件就好這裏是procps-3.3.9)
root@ubuntu:~# dpkg -S /bin/ps procps: /bin/ps root@ubuntu:~# ls ClionProjects Documents manpages-zh-1.5.1 Music Public Videos Desktop Downloads manpages-zh-1.5.1.tar.gz Pictures Templates root@ubuntu:~# cd Desktop/ root@ubuntu:~/Desktop# ls root@ubuntu:~/Desktop# apt-get source procps Reading package lists... Done Building dependency tree Reading state information... Done NOTICE: ‘procps‘ packaging is maintained in the ‘Git‘ version control system at: git://git.debian.org/collab-maint/procps.git Need to get 612 kB of source archives. Get:1 http://us.archive.ubuntu.com/ubuntu/ trusty-updates/main procps 1:3.3.9-1ubuntu2.3 (dsc) [2,164 B] Get:2 http://us.archive.ubuntu.com/ubuntu/ trusty-updates/main procps 1:3.3.9-1ubuntu2.3 (tar) [561 kB] Get:3 http://us.archive.ubuntu.com/ubuntu/ trusty-updates/main procps 1:3.3.9-1ubuntu2.3 (diff) [49.1 kB] Fetched 612 kB in 46s (13.3 kB/s) gpgv: Signature made 2018年05月14日 星期一 05時38分54秒 PDT using RSA key ID A744BE93 gpgv: Can‘t check signature: public key not found dpkg-source: warning: failed to verify signature on ./procps_3.3.9-1ubuntu2.3.dsc dpkg-source: info: extracting procps in procps-3.3.9 dpkg-source: info: unpacking procps_3.3.9.orig.tar.xz dpkg-source: info: unpacking procps_3.3.9-1ubuntu2.3.debian.tar.gz dpkg-source: info: applying uptime_test dpkg-source: info: applying ignore_eaccess.patch dpkg-source: info: applying testsuite_unsupp dpkg-source: info: applying pmap_test dpkg-source: info: applying libtool-update.diff dpkg-source: info: applying /p_pid-enum.diff dpkg-source: info: applying ignore_erofs.patch dpkg-source: info: applying CVE-2018-1122.patch dpkg-source: info: applying CVE-2018-1123.patch dpkg-source: info: applying CVE-2018-1124.patch dpkg-source: info: applying CVE-2018-1125.patch dpkg-source: info: applying CVE-2018-1126.patch dpkg-source: info: applying pmap_new_kernel.patch root@ubuntu:~/Desktop#
打開 clion 導入項目(註冊可以用遠程服務器http://idea.imsxm.com)
在 clion 裏就可以搜索指定目錄下所有文件中的字符串了(跟代碼審計一樣)
可以全選也可以默認
點擊項目
可以直接 ok查看 或者看預覽(preview)
找到 ps 真正的 main 函數:
其它用法就是clion 的用法了
如:可以查看函數、變量被誰引用了等等
這裏就直接給出我隨便提取的 demo(功能有 遍歷進程 與特定進程的內存)
#include <iostream> #include <cstring> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <dirent.h> #include <sys/ptrace.h> #include <wait.h> void test1(){ // alt + enter 排錯 // ctrl + q 查看文檔 FILE* fp = fopen("hello.txt", "a+"); if(fp == NULL){ std::cout << "open file error" << std::endl; return; } char szBuf[100] = {"hello world!"}; fwrite(szBuf,strlen(szBuf),1,fp); fclose(fp); } void test2(){ // alt + enter 排錯 // ctrl + q 查看文檔 FILE* fp = fopen("hello.txt", "r+"); if(fp == NULL){ std::cout << "open file error" << std::endl; return; } int nFileSize = 0; struct stat stcFileInfo = {0}; stat("hello.txt", &stcFileInfo); nFileSize = stcFileInfo.st_size; char szBuf[100] = {}; fread(szBuf,nFileSize,1,fp); fclose(fp); printf("read content : %s ",szBuf); } void test3(){ // 1. open file int fd = open("hello1.txt", O_WRONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO); if(fd == -1){ perror("open error"); return; } // 2. write file char szBuf[100] = {"hello world!"}; int nRet = write(fd, szBuf, strlen(szBuf)); if(nRet == -1){ perror("write error"); return; } // 3. close file close(fd); } void test4(){ // 1. open file int fd = open("hello1.txt", O_RDONLY); if(fd == -1){ perror("open error"); return; } // 2. write file int nFileSize = 0; struct stat stcFileInfo = {0}; stat("hello.txt", &stcFileInfo); nFileSize = stcFileInfo.st_size; char szBuf[100] = {0}; int nRet = read(fd, szBuf, nFileSize); if(nRet == -1){ perror("read error"); return; } // 3. close file close(fd); printf("read content 1 : %s ",szBuf); } void enumProcess(){ struct dirent *ent; /* dirent handle */ DIR *dir; int ouruid; int found_a_proc; found_a_proc = 0; ouruid = getuid(); dir = opendir("/proc"); while(( ent = readdir(dir) )){ if(*ent->d_name<‘0‘ || *ent->d_name>‘9‘) continue; int pid = atoi(ent->d_name); char p_cmd[16] = {0}; char buf[800]; /* about 40 fields, 64-bit decimal is about 20 chars */ int num; int fd; char* tmp; struct stat sb; /* stat() used to get EUID */ snprintf(buf, 32, "/proc/%d/stat", pid); if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return; num = read(fd, buf, sizeof buf - 1); fstat(fd, &sb); close(fd); buf[num] = ‘\0‘; tmp = strrchr(buf, ‘)‘); /* split into "PID (cmd" and "<rest>" */ *tmp = ‘\0‘; /* replace trailing ‘)‘ with NUL */ sscanf(buf, "%d (%15c", &pid, p_cmd); /* comm[16] in kernel */ printf("pid = %d name = %s \r\n", pid, p_cmd); } closedir(dir); } void show_info(const char* buf, int size) { int count = 0; while(count < size){ char ch = buf[count++]; char show[10] = {0}; sprintf(show, "%02x ", (u_char)ch); printf("%s",show); if ((count % 16) == 0){ printf("\r\n"); } } } void readProcessMem(int pid){ // 1. attach process long lRet = ptrace(PTRACE_ATTACH, pid,NULL,NULL); if(lRet == -1){ perror("ptrace err"); return; } // 2. wait pid int stat = 0; __pid_t pid1 = waitpid(pid, &stat, 0); if(pid1 == -1){ perror("waitpid err"); return; } // 3. open mem char szBuf[100] ={0}; sprintf(szBuf, "/proc/%d/mem", pid); int fd = open(szBuf,O_RDONLY); if(fd == -1){ perror("open err"); return; } // 4. lseek pos int nRet = lseek(fd, 0x55c266915000, SEEK_SET); if(nRet == -1){ perror("lseek err"); return; } // 5. read mem char buf[0x200] = {0}; nRet = read(fd, buf, 200); if(nRet == -1){ perror("read err"); return; } // 6. close close(fd); ptrace(PTRACE_DETACH, pid, 0,0); // 7, show show_info(buf, 200); } int main() { enumProcess(); int pid = 0; printf("please input pid :"); scanf("%d", &pid); readProcessMem(pid); getchar(); return 0; }
如何在linux下閱讀源碼以及提取寫簡單demo