Как может А. файл bat будет "преобразован".exe без сторонних инструментов?

есть много причин, чтобы хотеть "конвертировать" a .bat до .exe - скрыть / запутать реализацию, пароли, путь к ресурсам, создать сервис из пакетного файла ... и главным образом, чтобы ваша работа выглядела более сложной и важной, чем она есть на самом деле.

есть также много причин, чтобы не использовать сторонние инструменты.

Ну и что, если вы хотите "конвертировать" пакетный файл в .exe без внешнего программного обеспечения? (конвертировать в кавычках, потому что я не думаю, есть действительно способ скомпилировать пакетный файл в исполняемый файл. Есть слишком много оскорбительных извилистых методов и ошибок, широко используемых, и все инструменты, которые я знаю, на самом деле создают временный .bat файл, а затем вызовите его)

1 ответов


один очень очевидный подход-использовать IEXPRESS - древний встроенный инструмент, который создает самораспаковывающиеся пакеты и способен выполнять команды извлечения post. Так вот IEXPRESS sed-директива/.файл bat, который создает самораспаковывающийся.exe с упакованные .летучая мышь. Он принимает два аргумента-свой .bat-файл, который вы хотите преобразовать и целевой исполняемый файл:

 ;@echo off
; rem https://github.com/npocmaka/batch.scripts/edit/master/hybrids/iexpress/bat2exeIEXP.bat
;if "%~2" equ "" (
; echo usage: %~nx0 batFile.bat target.Exe
;)
;set "target.exe=%__cd__%%~2"
;set "batch_file=%~f1"
;set "bat_name=%~nx1"
;set "bat_dir=%~dp1"

;copy /y "%~f0" "%temp%exe.sed" >nul

;(echo()>>"%temp%exe.sed"
;(echo(AppLaunched=cmd.exe /c "%bat_name%")>>"%temp%exe.sed"
;(echo(TargetName=%target.exe%)>>"%temp%exe.sed"
;(echo(FILE0="%bat_name%")>>"%temp%exe.sed"
;(echo([SourceFiles])>>"%temp%exe.sed"
;(echo(SourceFiles0=%bat_dir%)>>"%temp%exe.sed"
;(echo([SourceFiles0])>>"%temp%exe.sed"
;(echo(%%FILE0%%=)>>"%temp%exe.sed"


;iexpress /n /q /m %temp%exe.sed

;del /q /f "%temp%exe.sed"
;exit /b 0

[Version]
Class=IEXPRESS
SEDVersion=3
[Options]
PackagePurpose=InstallApp
ShowInstallProgramWindow=0
HideExtractAnimation=1
UseLongFileName=1
InsideCompressed=0
CAB_FixedSize=0
CAB_ResvCodeSigning=0
RebootMode=N
InstallPrompt=%InstallPrompt%
DisplayLicense=%DisplayLicense%
FinishMessage=%FinishMessage%
TargetName=%TargetName%
FriendlyName=%FriendlyName%
AppLaunched=%AppLaunched%
PostInstallCmd=%PostInstallCmd%
AdminQuietInstCmd=%AdminQuietInstCmd%
UserQuietInstCmd=%UserQuietInstCmd%
SourceFiles=SourceFiles

[Strings]
InstallPrompt=
DisplayLicense=
FinishMessage=
FriendlyName=-
PostInstallCmd=<None>
AdminQuietInstCmd=
UserQuietInstCmd=

пример:

bat2exeIEXP.bat  myBatFile.bat MyExecutable.exe

это должно работать практически на каждой машине Windows есть, но есть одно основное ограничение-вы не можете передавать аргументы созданному .exe файл

таким образом, еще один возможный подход-посмотреть на компиляторы .NET (снова должен быть доступен почти на каждой машине win).Я выбрал Jscript.net . Это гибрид jscript.net/.bat скрипт, который будет читать .содержимое пакетного файла.Создам еще jscript.net с помощью .содержимое файла bat и после компиляции создаст новый bat файл в папке temp и будет вызывать его.И примет аргументы командной строки.(объяснено может выглядеть сложным, но на самом деле это просто):

@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal

del %~n0.exe /q /s >nul 2>nul

for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
   set "jsc=%%v"
)

if not exist "%~n0.exe" (
    "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)

%~n0.exe  "%jsc%" %*
del /q /f %~n0.exe 1>nul 2>nul 
endlocal & exit /b %errorlevel%
*/

//https://github.com/npocmaka/batch.scripts/blob/master/hybrids/.net/bat2exe.bat
import System;
import System;
import System.IO;
import  System.Diagnostics;


var arguments:String[] = Environment.GetCommandLineArgs();
if (arguments.length<3){
    Console.WriteLine("Path to cmd\bat file not given");
    Environment.Exit(1);
}

var binName=Path.GetFileName(arguments[2])+".exe";
if(arguments.length>3){
    binName=Path.GetFileName(arguments[3]);
}
var batchContent:byte[]= File.ReadAllBytes(arguments[2]);
var compilerLoc=arguments[1];

var content="["

for (var i=0;i<batchContent.length-1;i++){
    content=content+batchContent[i]+","
}
content=content+batchContent[batchContent.length-1]+"]";
var temp=Path.GetTempPath();
var dt=(new Date()).getTime();
var tempJS=temp+"\2exe"+dt+".js";


var toCompile="\r\n\
import System;\r\n\
import System.IO;\r\n\
import  System.Diagnostics;\r\n\
var batCommandLine:String='';\r\n\
//Remove the executable name from the command line\r\n\
try{\r\n\
var arguments:String[] = Environment.GetCommandLineArgs();\r\n\
batCommandLine=Environment.CommandLine.substring(arguments[0].length,Environment.CommandLine.length);\r\n\
}catch(e){}\r\n\
var content2:byte[]="+content+";\r\n\
var dt=(new Date()).getTime();\r\n\
var temp=Path.GetTempPath();\r\n\
var nm=Process.GetCurrentProcess().ProcessName.substring(0,Process.GetCurrentProcess().ProcessName.length-3);\r\n\
var tempBatPath=Path.Combine(temp,nm+dt+'.bat');\r\n\
File.WriteAllBytes(tempBatPath,content2);\r\n\
var pr=System.Diagnostics.Process.Start('cmd.exe','/c '+' '+tempBatPath+' '+batCommandLine);\r\n\
pr.WaitForExit();\r\n\
File.Delete(tempBatPath);\r\n\
";

File.WriteAllText(tempJS,toCompile);
var pr=System.Diagnostics.Process.Start(compilerLoc,'/nologo /out:"'+binName+'" "'+tempJS+'"');
pr.WaitForExit();
File.Delete(tempJS);

это скорее POC, но .NET-система.Диагностика и система.Библиотеки ввода-вывода достаточно мощные, чтобы добавлять такие функции , как скрытый запуск, enctiption и т. д.Вы можете проверить также АО.параметры компиляции exe, чтобы увидеть, что еще способно (например, добавление ресурсов).

обещаю проголосовать за каждое улучшение .Чистый способ :-)

обновление: второй скрипт был изменен, и теперь exe из конвертированного файла bat можно запустить двойным щелчком мыши.Он использует тот же интерфейс, что и предыдущий скрипт:

bat2exejs.bat example.bat example.exe