EXE/DLL -> com変換ツール
EXE/DLL -> com変換ツール
編集箇所
PE勉強会#2の資料より。EXE/DLL(PE形式)からCOM形式に変更するために。
- 0000 - 003Fを削除
- DOS EXEのヘッダ
- 0044を00 -> 01に
- COMはアドレス0100から始まるので、そのための調整?
ソースコード
#include <stdio.h> /* convert.c * * this program converts exe/dll file to com file. */ void usage( char **argv ) { printf( "usage : %s <input binary file> <output binary file>\n", argv[ 0 ] ) ; return ; } int main( int argc, char **argv ) { FILE *fin, *fout ; int c ; unsigned int i = 0 ; if( argc != 3 ) { usage( argv ) ; return -1 ; } if( ! ( fin = fopen( argv[ 1 ], "rb" ) ) ) { printf( "failed to open input file.\n" ) ; return -1 ; } if( ! ( fout = fopen( argv[ 2 ], "wb" ) ) ) { printf( "failed to open output file.\n" ) ; fclose( fin ) ; return -1 ; } while( ( c = getc( fin ) ) != EOF ) { if( i > 63 ) { if( i == 68 ) putc( 1, fout ) ; else putc( c, fout ) ; } i++ ; } fclose( fin ) ; fclose( fout ) ; return 0 ; }
実行例
% gcc -o convert.exe convert.c % ./convert.exe ./dump.exe ./dump.com % debug dump.com -g This program cannot be run in DOS mode. プログラムは正常に終了しました.
DLLを使用したもの
前回のエントリではPE形式かを判定するツールを作りました。このツールを組み込んで、入力ファイルがPE形式でない場合処理を中断するように変更しました。
PE判定ツール(judge.c)はDLLにしてみました。
ソースコード
PE判定DLLのソース。
#include <stdio.h> /* judge2.c * * this program is made from judge.c with some tune. * * return 1 : file is PE. * 0 : file is not PE. * -1 : error. */ int judge( char *filename ) { FILE *fp ; int c ; unsigned int i = 0, head_addr = 0, valid = 0 ; if( ! ( fp = fopen( filename, "rb" ) ) ) { printf( "failed to open file.\n" ) ; return -1 ; } while( ( c = getc( fp ) ) != EOF ) { if( i == 0 ) { if( c != 77 ) break ; } else if( i == 1 ) { if( c != 90 ) break ; } else if( i >= 60 && i <= 63 ) { head_addr += ( c << ( ( i - 60 ) * 8 ) ) ; } else if( head_addr ) { if( i == head_addr ) { if( c != 80 ) break ; } else if( i == head_addr + 1 ) { if( c != 69 ) break ; } else if( i == head_addr + 2 ) { if( c != 0 ) break ; } else if( i == head_addr + 3 ) { if( c == 0 ) valid = 1 ; break ; } else if( i > head_addr + 3 ) { break ; } } i++ ; } fclose( fp ) ; return valid ; }
本体のソース。
#include <stdio.h> /* convert2.c * * this program is made from convert.c with some tune. */ void usage( char **argv ) { printf( "usage : %s <input binary file> <output binary file>\n", argv[ 0 ] ) ; return ; } int main( int argc, char **argv ) { FILE *fin, *fout ; int c ; unsigned int i = 0 ; if( argc != 3 ) { usage( argv ) ; return -1 ; } if( ! judge( argv[ 1 ] ) ) { printf( "input file is not EXE/DLL file.\n" ) ; return -1 ; } if( ! ( fin = fopen( argv[ 1 ], "rb" ) ) ) { printf( "failed to open input file.\n" ) ; return -1 ; } if( ! ( fout = fopen( argv[ 2 ], "wb" ) ) ) { printf( "failed to open output file.\n" ) ; fclose( fin ) ; return -1 ; } while( ( c = getc( fin ) ) != EOF ) { if( i > 63 ) { if( i == 68 ) putc( 1, fout ) ; else putc( c, fout ) ; } i++ ; } fclose( fin ) ; fclose( fout ) ; return 0 ; }
実行例
% gcc -shared -o ./judge.dll ./judge2.c % gcc -o ./convert2.exe ./convert2.c ./judge.dll % ./convert2.exe ./dump.exe ./dump.com % debug dump.com -g This program cannot be run in DOS mode. プログラムは正常に終了しました.