@@ -53,6 +53,33 @@ BYTE* shellcodify(BYTE *my_exe, size_t exe_size, size_t &out_size, bool is64b)
5353 return ext_buf;
5454}
5555
56+ template <typename IMAGE_TLS_DIRECTORY >
57+ bool has_tls_callbacks (BYTE *my_exe, size_t exe_size)
58+ {
59+ IMAGE_DATA_DIRECTORY * tls_dir = peconv::get_directory_entry (my_exe, IMAGE_DIRECTORY_ENTRY_TLS );
60+ if (!tls_dir) return false ;
61+
62+ IMAGE_TLS_DIRECTORY * tls = peconv::get_type_directory<IMAGE_TLS_DIRECTORY >((HMODULE )my_exe, IMAGE_DIRECTORY_ENTRY_TLS );
63+ if (!tls) return false ;
64+
65+ ULONGLONG base = peconv::get_image_base (my_exe);
66+ ULONGLONG callback_rva = tls->AddressOfCallBacks ;
67+ if (callback_rva > base) {
68+ callback_rva -= base;
69+ }
70+ if (!peconv::validate_ptr (my_exe, exe_size, my_exe + callback_rva, sizeof (ULONGLONG ))) {
71+ return false ;
72+ }
73+ ULONGLONG *callback_addr = (ULONGLONG *)(my_exe + callback_rva);
74+ if (callback_addr == 0 ) {
75+ return false ;
76+ }
77+ if (*callback_addr == 0 ) {
78+ return false ;
79+ }
80+ return true ;
81+ }
82+
5683bool is_supported_pe (BYTE *my_exe, size_t exe_size)
5784{
5885 if (!my_exe) return false ;
@@ -70,7 +97,40 @@ bool is_supported_pe(BYTE *my_exe, size_t exe_size)
7097 }
7198 IMAGE_DATA_DIRECTORY * tls_dir = peconv::get_directory_entry (my_exe, IMAGE_DIRECTORY_ENTRY_TLS );
7299 if (tls_dir) {
73- std::cout << " [WARNING] This application may have TLS callbacks, which are not supported!" << std::endl;
100+ bool has_callback = false ;
101+ if (!peconv::is64bit (my_exe)) {
102+ if (has_tls_callbacks<IMAGE_TLS_DIRECTORY32 >(my_exe, exe_size)) {
103+ has_callback = true ;
104+ }
105+ }
106+ else {
107+ if (has_tls_callbacks<IMAGE_TLS_DIRECTORY64 >(my_exe, exe_size)) {
108+ has_callback = true ;
109+ }
110+ }
111+ if (has_callback) {
112+ std::cout << " [WARNING] This application has TLS callbacks, which are not supported!" << std::endl;
113+ }
114+ }
115+ return true ;
116+ }
117+
118+ bool is_supported_pe (const std::string &in_path)
119+ {
120+ std::cout << " Reading module from: " << in_path << std::endl;
121+ size_t exe_size = 0 ;
122+ BYTE *my_exe = peconv::load_pe_module (in_path.c_str (), exe_size, false , false );
123+ if (!my_exe) {
124+ std::cout << " [-] Could not read the input file!" << std::endl;
125+ return false ;
126+ }
127+
128+ bool is_ok = is_supported_pe (my_exe, exe_size);
129+ peconv::free_pe_buffer (my_exe);
130+
131+ if (!is_ok) {
132+ std::cout << " [-] Not supported input file!" << std::endl;
133+ return false ;
74134 }
75135 return true ;
76136}
@@ -93,24 +153,23 @@ int main(int argc, char *argv[])
93153 return 0 ;
94154 }
95155
96- size_t exe_size = 0 ;
97156 std::string in_path = argv[1 ];
98157 std::string out_str = make_out_name (in_path);
99158 if (argc > 2 ) {
100159 out_str = argv[2 ];
101160 }
102161
103- std::cout << " Reading module from: " << in_path << std::endl;
162+ if (!is_supported_pe (in_path)) {
163+ return -2 ;
164+ }
165+
166+ size_t exe_size = 0 ;
104167 BYTE *my_exe = peconv::load_file (in_path.c_str (), exe_size);
105168 if (!my_exe) {
106169 std::cout << " [-] Could not read the input file!" << std::endl;
107170 return -1 ;
108171 }
109- if (!is_supported_pe (my_exe, exe_size)) {
110- std::cout << " [-] Not supported input file!" << std::endl;
111- peconv::free_file (my_exe);
112- return -2 ;
113- }
172+
114173 bool is64b = peconv::is64bit (my_exe);
115174 size_t ext_size = 0 ;
116175 BYTE *ext_buf = shellcodify (my_exe, exe_size, ext_size, is64b);
0 commit comments