PE Write Section(写入一个节)
本帖最后由 whypro 于 2010-5-26 14:04 编辑/*
. .: .:.. :.. .. .:.::. :. ..:
<<-==苒圹圹?苒圹圹?苒圹圹?==<
.:: 圹?圹?圹?圹?圹?圹?.:.
. .:.苘苒圻.咣圹圹?圹圹圹?..
...圹圮苘?苘苘圹?圹?圹?::.
>===圹圹圹?圹圹圹?圹?圹?->>
.: .:.. ..:. .: ..:.::. ::.. :.:.
PE Write Section, by Jacky Qwerty/29A
Here's a new utility from 29A. This program simply sets thewrite bit to a
section in a PE file. This is needed when you need write access to the code
section in afirst generation sample,for instance.There is one utility
from the SDK (EDITBIN) which does exactly the same thing with PE filez, but
it needs some huge DLLz from VC to work.On the other hand, PEWRSEC can be
compiled as a stupid COM file. Hope this will be handy enough for you ;)
*/
29A杂志里的一篇文章,通过c语言文件操作来搞定添加新节的功能。
VC++编译成功!
/*- -- - - - - - - - - - - - - - - - - - - - - - - - - - - ->8 */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "mz.h"
#include "pe.h"
#define SizeBuffMZ sizeof(IMAGE_DOS_HEADER)
#define SizeBuffPE (4 + IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_STD_OPTIONAL_HEADER)
#define SizeBuffSH IMAGE_SIZEOF_SECTION_HEADER
#define SizeBuffMax max(SizeBuffMZ, max(SizeBuffPE, SizeBuffSH))
INT Strncmpz(BYTE *S1, BYTE *S2, INT Count) {
while (Count--) {
if (*S1 < *S2) return -1;// This fucntion doesnt seem to be implemented
if (*S1 > *S2++) return 1; // in the standard C string library, It combines
if (!*S1++) break; } // the funtionality of "strcmp" and "strncmp".
return 0;
}
INT main(INT argc, CHAR *argv[]) {
FILE *File;
INT RetValue = 1;
PCHAR SecName = NULL, FileName = NULL;
WORD Sections;
PIMAGE_DOS_HEADER pMZ;
PIMAGE_NT_HEADERS pPE;
PIMAGE_SECTION_HEADER pSH;
CHAR Buffer;
printf("PEWRSEC - Sets the WRITE bit to a PE section - (c) 1997 jqwerty/29A\n\n");
if (argc != 2 && argc != 3) {
printf("Syntax: PEWRSEC <FileName>(default: code section)\n");
Ret: return RetValue; }
while (--argc) {
if (*argv != '/') {
if ((FileName = argv) == NULL) { printf("No filename specified\n"); goto Ret; } }
else if (!strncmpi(argv + 1, "SEC:", 4)) SecName = argv + 5;
else { printf("Unknown option '%s'\n", argv); goto Ret; } }
if ((File = fopen(FileName, "rb+")) == 0) {
printf("Can't open '%s'\n", FileName); goto Ret; }
if (!fread(pMZ = (PIMAGE_DOS_HEADER)Buffer, SizeBuffMZ, 1, File)) {
ReadErr:
if (!feof(File)) { printf("Error reading file\n"); CloseFile: fclose(File); goto Ret; }
else { InvalidPE: printf("Not a valid PE file\n"); goto CloseFile; } }
if (pMZ->e_magic != IMAGE_DOS_SIGNATURE) goto InvalidPE;
if (fseek(File, pMZ->e_lfanew, SEEK_SET)) {
SeekErr:
if (errno != EBADF) { printf("Error in file seek\n"); goto CloseFile; }
else goto InvalidPE; }
if (!fread(pPE = (PIMAGE_NT_HEADERS)Buffer, SizeBuffPE, 1, File)) goto ReadErr;
if (pPE->Signature != IMAGE_NT_SIGNATURE || !(Sections = pPE->FileHeader.NumberOfSections)) goto InvalidPE;
if (fseek(File, FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + pPE->FileHeader.SizeOfOptionalHeader - SizeBuffPE, SEEK_CUR)) goto SeekErr;
do {
if (!fread(pSH = (PIMAGE_SECTION_HEADER)Buffer, SizeBuffSH, 1, File)) goto ReadErr;
if (SecName) { if (!Strncmpz(SecName, pSH->Name, 8)) break; }
else if (pSH->VirtualAddress <= pPE->OptionalHeader.AddressOfEntryPoint && pPE->OptionalHeader.AddressOfEntryPoint < pSH->VirtualAddress + pSH->Misc.VirtualSize) break;
} while (--Sections);
if (!Sections) { printf("Section not found\n"); goto CloseFile; }
if (!(pSH->Characteristics & IMAGE_SCN_MEM_WRITE)) {
pSH->Characteristics |= IMAGE_SCN_MEM_WRITE;
if (fseek(File, - SizeBuffSH, SEEK_CUR)) goto SeekErr;
if (!fwrite(pSH, SizeBuffSH, 1, File) || fflush(File)) {
printf("Error writing file\n"); goto CloseFile; } }
printf("Ok\n"); RetValue = 0; goto CloseFile;
}
主程序就这么两行?我们一行一行分析! 3-9行是文件头
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"<------------自定义类型
#include "mz.h"<------------dos文件头
#include "pe.h" <------------pe文件头 本帖最后由 whypro 于 2010-5-26 14:26 编辑
11-14行
参考pe.h文件头
#define SizeBuffMZ sizeof(IMAGE_DOS_HEADER)
返回IMAGE_DOS_HEADER大小存入SizeBuffMZ
#define SizeBuffPE (4 + IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_STD_OPTIONAL_HEADER)
IMAGE_NT_HEADERS大小存入SizeBuffPE
#define SizeBuffSH IMAGE_SIZEOF_SECTION_HEADER
IMAGE_SECTION_HEADER大小存入SizeBuffSH
#define SizeBuffMax max(SizeBuffMZ, max(SizeBuffPE, SizeBuffSH))
#define max(a,b) (((a) > (b)) ? (a) : (b))
返回最大那个存SizeBuffMax 本帖最后由 whypro 于 2010-5-26 14:38 编辑
16-22行
自定义函数比较两个字符的大小!
INT Strncmpz(BYTE *S1, BYTE *S2, INT Count) {
while (Count--) {
if (*S1 < *S2) return -1;// This fucntion doesnt seem to be implemented
if (*S1 > *S2++) return 1; // in the standard C string library, It combines
if (!*S1++) break; } // the funtionality of "strcmp" and "strncmp".
return 0;
}
和它的功能差不多一样
int strncmp ( const char * str1, const char * str2, size_t num );
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = { "R2D2" , "C3PO" , "R2A6" };
int n;
puts ("Looking for R2 astromech droids...");
for (n=0 ; n<3 ; n++)
if (strncmp (str,"R2xx",2) == 0)
{
printf ("found %s\n",str);
}
return 0;
}
Looking for R2 astromech droids...
found R2D2
found R2A6 本帖最后由 whypro 于 2010-5-26 14:46 编辑
24-36行
INT main(INT argc, CHAR *argv[]) {
FILE *File;
INT RetValue = 1;
PCHAR SecName = NULL, FileName = NULL;
WORD Sections;
PIMAGE_DOS_HEADER pMZ;
PIMAGE_NT_HEADERS pPE;
PIMAGE_SECTION_HEADER pSH;
CHAR Buffer;
_________________________________分割线 结构,变量,数组都有体现 ——————————————————————
printf("PEWRSEC - Sets the WRITE bit to a PE section - (c) 1997 jqwerty/29A\n\n");
if (argc != 2 && argc != 3) {
printf("Syntax: PEWRSEC <FileName>(default: code section)\n");
Ret: return RetValue; }
命令行参数argc请看 我以前发的贴 好了 就剩printf了自己玩吧! 37-41行
while (--argc) {
if (*argv != '/') {
if ((FileName = argv) == NULL) { printf("No filename specified\n"); goto Ret; } }
else if (!Strncmpz(argv + 1, "SEC:", 4)) SecName = argv + 5;
else { printf("Unknown option '%s'\n", argv); goto Ret; } } 本帖最后由 whypro 于 2010-5-26 14:52 编辑
if ((File = fopen(FileName, "rb+")) == 0) {
printf("Can't open '%s'\n", FileName); goto Ret; }
if (!fread(pMZ = (PIMAGE_DOS_HEADER)Buffer, SizeBuffMZ, 1, File)) {
ReadErr:
if (!feof(File)) { printf("Error reading file\n"); CloseFile: fclose(File); goto Ret; }
else { InvalidPE: printf("Not a valid PE file\n"); goto CloseFile; } }
if (pMZ->e_magic != IMAGE_DOS_SIGNATURE) goto InvalidPE;
if (fseek(File, pMZ->e_lfanew, SEEK_SET)) {
SeekErr:
if (errno != EBADF) { printf("Error in file seek\n"); goto CloseFile; }
else goto InvalidPE; }
if (!fread(pPE = (PIMAGE_NT_HEADERS)Buffer, SizeBuffPE, 1, File)) goto ReadErr;
if (pPE->Signature != IMAGE_NT_SIGNATURE || !(Sections = pPE->FileHeader.NumberOfSections)) goto InvalidPE;
if (fseek(File, FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + pPE->FileHeader.SizeOfOptionalHeader - SizeBuffPE, SEEK_CUR)) goto SeekErr; do {
if (!fread(pSH = (PIMAGE_SECTION_HEADER)Buffer, SizeBuffSH, 1, File)) goto ReadErr;
if (SecName) { if (!Strncmpz(SecName, pSH->Name, 8)) break; }
else if (pSH->VirtualAddress <= pPE->OptionalHeader.AddressOfEntryPoint && pPE->OptionalHeader.AddressOfEntryPoint < pSH->VirtualAddress + pSH->Misc.VirtualSize) break;
} while (--Sections); 本帖最后由 whypro 于 2010-5-26 14:53 编辑
if (!Sections) { printf("Section not found\n"); goto CloseFile; }
if (!(pSH->Characteristics & IMAGE_SCN_MEM_WRITE)) {
pSH->Characteristics |= IMAGE_SCN_MEM_WRITE;
if (fseek(File, - SizeBuffSH, SEEK_CUR)) goto SeekErr;
if (!fwrite(pSH, SizeBuffSH, 1, File) || fflush(File)) {
printf("Error writing file\n"); goto CloseFile; } }
printf("Ok\n"); RetValue = 0; goto CloseFile;
页:
[1]