|
|
|
[求助]PE文件的问题
//写入新的块表 fwrite(&NewSection,sizeof(IMAGE_SECTION_HEADER),1,newfile); if(NThea.OptionalHeader.SizeOfCode==pOH->SizeOfCode)printf("\n124.llydd\n"); int nNewImageSize=NThea.OptionalHeader.SizeOfImage+alig(nShellLen,SECTION_ALIG); int nNewSizeofCode=NThea.OptionalHeader.SizeOfCode+alig(nShellLen,FILE_ALIG); fseek(newfile,pNT,0); NThea.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress=0; NThea.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size=0; if(NThea.OptionalHeader.SizeOfCode==pOH->SizeOfCode)printf("\n191.d\n");//这个等式成立 NThea.OptionalHeader.SizeOfCode=nNewSizeofCode; //但是把NThea.OptionalHeader.SizeOfCode用pOH->SizeOfCode替代会出现 Unhandled exception:0xC000005:Access Violation ,不替代正确运行 //写入更新后的PE头结构 fwrite(&NThea,sizeof(IMAGE_NT_HEADERS),1,newfile printf("\t\tok.........!\n"); fclose(newfile); fclose(rwFile); return 0; |
|
[求助]PE文件的问题
那为什么把NThea.OptionalHeader.SizeOfCode=nNewSizeofCode;中的NThea.OptionalHeader.SizeOfCode换成pOH->SizeOfCode会出错 这是为什么 |
|
[求助]新手学习llydd的为PE文件增加新节,并在新节中增入SHELL CODE加载指定DLL一文的疑问
在软件加密技术内幕中说 GetNtHeaders(LPVOID ImageBase) GetOptionalHeader(LPVOID ImageBase) GetFileHeader(LPVOID ImageBase) 这些函数能得到PE信息 与下面的方法得到的有什么不同啊? IMAGE_NT_HEADERS NThea; fseek(rwFile,0x3c,0); DWORD pNT; //pNT中存放IMAGE_NT_HEADERS结构的地址 fread(&pNT,sizeof(DWORD),1,rwFile); fseek(rwFile,pNT,0); fread(&NThea,sizeof(IMAGE_NT_HEADERS),1,rwFile); //读取原文件的IMAGE_NT_HEADERS结构 得到的头信息是一样的吗?/?? |
|
[求助]新手学习llydd的为PE文件增加新节,并在新节中增入SHELL CODE加载指定DLL一文的疑问
具体代码如下: #include <windows.h> #include <stdio.h> #include <io.h> #include <fcntl.h> #include <time.h> #include <SYS\STAT.H> #include <poppack.h> #include <pshpack1.h> #include <iostream.h> int alig(int size,unsigned int align) { if(size%align!=0) return (size/align+1)*align; else return size; } int map_exe(const void *base) { IMAGE_DOS_HEADER * dos_head; dos_head =(IMAGE_DOS_HEADER *)base; typedef struct PE_HEADER_MAP { DWORD signature; IMAGE_FILE_HEADER _head; IMAGE_OPTIONAL_HEADER opt_head; IMAGE_SECTION_HEADER section_header[8]; } peHeader; if (dos_head->e_magic != IMAGE_DOS_SIGNATURE) { puts("unknown type of file"); return 0; } else printf("IS type of filen\n"); peHeader * header; header = (peHeader *)((char *)dos_head + dos_head->e_lfanew);//得到PE文件头 if (IsBadReadPtr(header, sizeof(*header))) { puts("(no PE header, probably DOS executable)\n"); return 0; } else {puts("( PE header, NO probably DOS executable)"); cout<< IMAGE_DOS_SIGNATURE ; return 1; } } PIMAGE_NT_HEADERS GetNtHeaders(LPVOID ImageBase) { if(!map_exe(ImageBase)) return NULL; PIMAGE_NT_HEADERS pNtH; PIMAGE_DOS_HEADER pDH; pDH=(PIMAGE_DOS_HEADER)ImageBase; pNtH=(PIMAGE_NT_HEADERS)((DWORD)pDH+pDH->e_lfanew); return pNtH; } // PIMAGE_FILE_HEADER GetFileHeader(LPVOID ImageBase) { PIMAGE_DOS_HEADER pDH=NULL; PIMAGE_NT_HEADERS pNtH=NULL; PIMAGE_FILE_HEADER pFH=NULL; if(!map_exe(ImageBase)) return NULL; pDH=(PIMAGE_DOS_HEADER)ImageBase; pNtH=(PIMAGE_NT_HEADERS)((DWORD)pDH+pDH->e_lfanew); pFH=&pNtH->FileHeader; return pFH; } PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPVOID ImageBase) { PIMAGE_DOS_HEADER pDH=NULL; PIMAGE_NT_HEADERS pNtH=NULL; PIMAGE_OPTIONAL_HEADER pOH=NULL; if(!map_exe(ImageBase)) return NULL; pDH=(PIMAGE_DOS_HEADER)ImageBase; pNtH=(PIMAGE_NT_HEADERS)((DWORD)pDH+pDH->e_lfanew); pOH=&pNtH->OptionalHeader; return pOH; } int main(int argc,char **argv) { HANDLE hFile, hMapping; void *basepointer; FILETIME * Createtime; FILETIME * Accesstime; FILETIME * Writetime; Createtime = new FILETIME; Accesstime = new FILETIME; Writetime = new FILETIME; PIMAGE_FILE_HEADER pFH=NULL; PIMAGE_OPTIONAL_HEADER pOH=NULL; PIMAGE_NT_HEADERS pNtH; if ((hFile = CreateFile(argv[1], GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0)) == INVALID_HANDLE_VALUE)//打开要修改的文件 { puts("(could not open)"); return EXIT_FAILURE; } if(!GetFileTime(hFile,Createtime,Accesstime,Writetime)) { printf("\nerror getfiletime: %d\n",GetLastError()); } //得到要修改文件的创建、修改等时间 if (!(hMapping = CreateFileMapping(hFile, 0, PAGE_READONLY | SEC_COMMIT, 0, 0, 0))) { puts("(mapping failed)"); CloseHandle(hFile); return EXIT_FAILURE; } if (!(basepointer = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0))) { puts("(view failed)"); CloseHandle(hMapping); CloseHandle(hFile); return EXIT_FAILURE; } //把文件头映象存入baseointer CloseHandle(hMapping); CloseHandle(hFile); map_exe(basepointer);//得到相关地址 char szNewFile[10]="_New.exe"; if(!CopyFile(argv[1],szNewFile,0)) //若备份文件出错则退出 { printf("\t\tbak faild\n"); exit(-1); } IMAGE_NT_HEADERS NThea; FILE* rwFile; rwFile=fopen(argv[1],"rb"); fseek(rwFile,0x3c,0); pFH= GetFileHeader(basepointer); pOH=GetOptionalHeader(basepointer); pNtH=GetNtHeaders(basepointer); DWORD pNT; //pNT中存放IMAGE_NT_HEADERS结构的地址 fread(&pNT,sizeof(DWORD),1,rwFile); fseek(rwFile,pNT,0); fread(&NThea,sizeof(IMAGE_NT_HEADERS),1,rwFile); //读取原文件的IMAGE_NT_HEADERS结构 //保存原文件区块数量与OEP int nOldSectionNo=pFH->NumberOfSections; if(NThea.OptionalHeader.SizeOfCode==pOH->SizeOfCode)printf("\n121.llydd\n"); int OEP=pOH->AddressOfEntryPoint; int SECTION_ALIG=pOH->SectionAlignment; //保存文件对齐值与区块对齐值lignment; int FILE_ALIG=pOH->FileAlignment; //定义要添加的区块 IMAGE_SECTION_HEADER NewSection; //将该结构全部清零 memset(&NewSection, 0, sizeof(IMAGE_SECTION_HEADER)); //再定义一个区块,来存放原文件最后一个区块的信息 IMAGE_SECTION_HEADER SEChea; //读原文件最后一个区块的信息 fseek(rwFile,pNT+248,0); for(int i=0;i<nOldSectionNo;i++) fread(&SEChea,sizeof(IMAGE_SECTION_HEADER),1,rwFile); FILE *newfile=fopen(szNewFile,"rb+"); if(newfile==NULL) { printf("\t\tOpen bak file faild\n"); exit(-1); } fseek(newfile,SEChea.PointerToRawData+SEChea.SizeOfRawData,SEEK_SET); goto shellend; __asm { shell: PUSHAD MOV EAX,DWORD PTR FS:[30H] ;FS:[30H]指向PEB MOV EAX,DWORD PTR [EAX+0CH] ;获取PEB_LDR_DATA结构的指针 MOV EAX,DWORD PTR [EAX+1CH] ;获取LDR_MODULE链表表首结点的inInitializeOrderModuleList成员的指针 MOV EAX,DWORD PTR [EAX] ;LDR_MODULE链表第二个结点的inInitializeOrderModuleList成员的指针 MOV EAX,DWORD PTR [EAX+08H] ;inInitializeOrderModuleList偏移8h便得到Kernel32.dll的模块基址 MOV EBP,EAX ; 将Kernel32.dll模块基址地址放至kernel中 MOV EAX,DWORD PTR [EAX+3CH] ;指向IMAGE_NT_HEADERS MOV EAX,DWORD PTR [EBP+EAX+120] ;指向导出表 MOV ECX,[EBP+EAX+24] ;取导出表中导出函数名字的数目 MOV EBX,[EBP+EAX+32] ;取导出表中名字表的地址 ADD EBX,EBP PUSH WORD PTR 0X00 ;构造GetProcAddress字符串 PUSH DWORD PTR 0X73736572 PUSH DWORD PTR 0X64644163 PUSH DWORD PTR 0X6F725074 PUSH WORD PTR 0X6547 MOV EDX,ESP PUSH ECX F1: MOV EDI,EDX POP ECX DEC ECX TEST ECX,ECX JZ EXIT MOV ESI,[EBX+ECX*4] ADD ESI,EBP PUSH ECX MOV ECX,15 REPZ CMPSB TEST ECX,ECX JNZ F1 POP ECX MOV ESI,[EBP+EAX+36] ;取得导出表中序号表的地址 ADD ESI,EBP MOVZX ESI,WORD PTR[ESI+ECX*2] ;取得进入函数地址表的序号 MOV EDI,[EBP+EAX+28] ;取得函数地址表的地址 ADD EDI,EBP MOV EDI,[EDI+ESI*4] ;取得GetProcAddress函数的地址 ADD EDI,EBP PUSH WORD PTR 0X00 ;构造LoadLibraryA字符串 PUSH DWORD PTR 0X41797261 PUSH DWORD PTR 0X7262694C PUSH DWORD PTR 0X64616F4C PUSH ESP PUSH EBP CALL EDI ;调用GetProcAddress取得LoadLibraryA函数的地址 PUSH WORD PTR 0X00 ;构造test符串,测试新增节后的EXE是否能正常加载test.dll PUSH DWORD PTR 0X74736574 PUSH ESP CALL EAX EXIT: ADD ESP,36 ;平衡堆栈 POPAD } shellend: char *pShell; int nShellLen; __asm { LEA EAX,shell MOV pShell,EAX; LEA EBX,shellend SUB EBX,EAX MOV nShellLen,EBX } //写入SHELLCODE, for(i=0;i<nShellLen;i++) fputc(pShell[i],newfile); //SHELLCODE之后是跳转到原OEP的指令 NewSection.VirtualAddress=SEChea.VirtualAddress+alig(SEChea.Misc.VirtualSize,SECTION_ALIG); BYTE jmp = 0xE9; OEP=OEP-(NewSection.VirtualAddress+nShellLen)-5; fwrite(&jmp, sizeof(jmp), 1, newfile); fwrite(&OEP, sizeof(OEP), 1, newfile); //将最后增加的数据用0填充至按文件中对齐的大小 for(i=0;i<alig(nShellLen,FILE_ALIG)-nShellLen-5;i++) fputc('\0',newfile); if(NThea.OptionalHeader.SizeOfCode==pOH->SizeOfCode)printf("\n121.llydd\n"); //新区块中的数据 strcpy((char*)NewSection.Name,".llydd"); NewSection.PointerToRawData=SEChea.PointerToRawData+SEChea.SizeOfRawData; NewSection.Misc.VirtualSize=nShellLen; NewSection.SizeOfRawData=alig(nShellLen,FILE_ALIG); NewSection.Characteristics=0xE0000020;//新区块可读可写可执行 fseek(newfile,pNT+248+sizeof(IMAGE_SECTION_HEADER)*nOldSectionNo,0); //写入新的块表 fwrite(&NewSection,sizeof(IMAGE_SECTION_HEADER),1,newfile); if(NThea.OptionalHeader.SizeOfCode==pOH->SizeOfCode)printf("\n124.llydd\n"); int nNewImageSize=NThea.OptionalHeader.SizeOfImage+alig(nShellLen,SECTION_ALIG); int nNewSizeofCode=NThea.OptionalHeader.SizeOfCode+alig(nShellLen,FILE_ALIG); fseek(newfile,pNT,0); if(NThea.OptionalHeader.SizeOfCode==pOH->SizeOfCode)printf("\n121.llydd\n"); NThea.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress=0; NThea.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size=0; if(NThea.OptionalHeader.SizeOfCode==pOH->SizeOfCode)printf("\n191.d\n"); pOH->SizeOfCode=nNewSizeofCode; NThea.OptionalHeader.SizeOfImage=nNewImageSize; if(NThea.OptionalHeader.SizeOfCode==pOH->SizeOfCode)printf("\n171.llydd\n"); NThea.FileHeader.NumberOfSections=nOldSectionNo+1; NThea.OptionalHeader.AddressOfEntryPoint=NewSection.VirtualAddress; //写入更新后的PE头结构 fwrite(&NThea,sizeof(IMAGE_NT_HEADERS),1,newfile); printf("\t\tok.........!\n"); fclose(newfile); fclose(rwFile); return 1; } |
|
|
|
[原创]一段仿真PE加载器行为的程序
先收藏,再研究一下。 |
|
arp欺骗DIY
收下了,深入学习一下 |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值