1 (изменено: Rumata, 2020-11-02 03:05:38)

Тема: VBS: Обфускатор/деобфускатор VBScript

У нас на форуме есть старая тема WSH: обфускация и Microsoft Script Encoder. Но это немного или слишком не то, что нужно, потому что там больше про кодирование.

Меня же заинтересовало наличие скриптов, реализованных именно на VBScript. Для JavaScript есть реализации на JavaScript. Для VBScript тоже есть, но на Ruby и Python. Логично же иметь такое на именно VBScript. Например, некий файл с красивыми отступами и комментариями:


' Вежливая подпрограмма
Sub Greet()
    WScript.Echo "Hello, world!"
End Sub

' Проявляем вежливость
Greet

А на выходе обфускатора получаем:


Sub Greet():WScript.Echo"Hello, world!":End Sub:Greet

И в обратную сторону, естественно, с потерей коментариев.

Есть такие на VBScript или JScript?

( 2 * b ) || ! ( 2 * b )

2

Re: VBS: Обфускатор/деобфускатор VBScript

Rumata пишет:

Есть такие на VBScript или JScript?

Нет, ничего подобного не видел. Видел проект перевода VBS в JScript (как пример работы парсера VBS на JS), но он не впечатлил.

По сути Вы показываете пример минификации кода. Это частный случай обфускации. Для обфускации рекомендуют для начала преобразовать тело скрипта в AST (abstact syntax tree). Если же говорим об уменьшении кода путем удаления переносов строк, так и заменой ":" на переносы, то вполне можно это решить средствами JScript.

Если бы стояла острая задача написания такого VBS Minifier, то я бы смотрел в сторону клиент-серверных решений (что будет выдавать результат сервер - это второй вопрос при наличии существующих инструментов).

3

Re: VBS: Обфускатор/деобфускатор VBScript

Да. Меня интересовали именно minifier/beautifier. Клиент-сервер - это черезчур сложно для такой задачи. Тексты других языков минимифицируются и "максифицируются" в пределах одного скрипта (тот же JS). Но раз нет, значит нет.

( 2 * b ) || ! ( 2 * b )

4 (изменено: andypetr, 2020-11-16 16:50:36)

Re: VBS: Обфускатор/деобфускатор VBScript

Привет.
Речь ведь про такое?
(проверил на маленьком примере):
https://github.com/DoctorLai/VBScript_Obfuscator

5

Re: VBS: Обфускатор/деобфускатор VBScript

andypetr пишет:

Речь ведь про такое?

Нет. Мне не нужно шифрование, мне нужна минификация кода. Я видел этот проект и что-то похожее на него. Пример того, что я хотел бы видеть, приведен в первом сообщении. Задача не настолько важная, поэтому писать лень и хочется чего-то готового.

( 2 * b ) || ! ( 2 * b )

6

Re: VBS: Обфускатор/деобфускатор VBScript

Rumata
Сделал на браузерном JavaScript перевод из Single Line Style (в основе обычный парсер строковых литералов). На ":" в строках не реагирует, комментарии понимает. Открываем DevTools, вставляем в консоль код.


var vbs_code = `
Sub Greet():WScript.Echo"Hello, world!":End Sub:Greet

Dim a, iLen, bSpace, tmpX, tmpFull

Rem sText = ":'test'":iLen = Len(sText)

sText = ":'test'":iLen = Len(sText)

  For a = 1 To iLen
'    If a <> 1 Then 
'        If bSpace = True Then 
'            tmpX = UCase(mid(sText,a,1)) 
'            bSpace = False 
'        Else
'        tmpX=LCase(mid(sText,a,1))
'            If tmpX = " " Or tmpX = "'" Then bSpace = True
'        End if 
'    Else
'        tmpX = UCase(mid(sText,a,1))
'    End if 
 
 
   tmpFull = tmpFull & tmpX
  Next
  ProperCase = tmpFull
End Function`;


function getStringPos(quotesPos)
{
	var stringPos = [];
	var startString = -1;
	var stringStarted = false;

	for (var i=0; i<quotesPos.length; i++)
	{

		if (stringStarted){
			if (quotesPos[i][1] % 2 == 1)
			{
				stringStarted = false;
				stringPos.push([startString, quotesPos[i][0] + quotesPos[i][1] - 1]);
				continue;
			}

			continue;
		}
		else
		{
			if (quotesPos[i][1] % 2 == 0)
			{
				stringPos.push([quotesPos[i][0], quotesPos[i][0] + quotesPos[i][1] - 1]);
				continue;

			}
			else
			{
				stringStarted = true;
				startString = quotesPos[i][0];
				continue;
			}
		}
		  		
	}

	return stringPos;
}


var lines = vbs_code.split(/\n/g); 
var lines_result = [];

for (var l=0; l<lines.length; l++)
{
	let line = lines[l]; 
	let quotesPos = [];
	let stringPos = [];

	line.replace( /""*/g, (m,i)=>quotesPos.push([i, m.length])  );
	let strings = getStringPos(quotesPos);

	let comment_pos = -1;
	line.replace(/'|\brem\b/ig, (m,i)=>{ 
		if (comment_pos!=-1) return;

		if ( strings.filter(el=>i>el[0]&&i<el[1]).length==0) 
		{
			comment_pos = i;
			strings = strings.filter(el=>i>el[1]);
		}		
	
	});

	let result = line.replace(/:/g, (m, i)=>{
		if (comment_pos!=-1 && i>comment_pos) return m;		
		if (strings.filter(el=>i>el[0]&&i<el[1]).length ) return m; else return "\n";	
	});

	lines_result.push(result);
}

console.log(lines_result.join("\n"));

7

Re: VBS: Обфускатор/деобфускатор VBScript

Глянул повнимательнее на этот проект: https://github.com/noraj/vbsmin. Ребята написали неплохой "уменьшитель" VBScript, но на Ruby. Видимо есть у них такая необходимость.

Я не знаю Ruby, но там и так все понятно:
-- переписал на VBScript (лицензия MIT вроде бы позволяет), почти в лоб, пока с очень минимальной отпимизацией под язык
-- выкинул некоторые методы, сделал на публичных функциях, не стал оформлять в класс (потому как черновик только)
-- намеренно оставил все комментарии (с небольшими правками)
-- убрал избыточнные телодвижения с вводом/выводом - это дело вызывающей программы, а не модуля

Прогнал несколько раз свой модуль:
0. контрольный прогон через ruby 2.6.4p104 (2019-08-28 revision 67798) [x86_64-cygwin]

1.1. "уменьшил" исходный код модуля своим модулем
1.2. "уменьшенную" версию прогнал еще раз
Ожидаемый результаты: версии 1.1 и 1.2 совпадат с версией 0

2.1. "уменьшил" исходный код модуля уменьшенной весрией
2.2. "уменьшенную" версию прогнал еще раз
Ожидаемый результаты: "уменьшенная" версия работает; версии 2.1 и 2.2 совпадат с версией 0


' Minify a VBScript input (make a minified copy)
'
' @param  [String] original VBScript text
' @return [String] minified VBScript text
Function minify(text)
	Dim lines, i, line, result

	result = ""

	' Parse the entire text as separate lines
	lines = Split(text, Chr(10))

	For i = 0 To UBound(lines)
		line = lines(i)
		line = minify_line(line)
		If line <> "" Then
			result = result & line
		End If
	Next

	' Remove trailing ":", if any
	If Right(result, 1) = ":" Then
		result = Left(result, Len(result) - 1)
	End If

	minify = result
End Function

Function minify_line(line)
	Dim eol

	'  End of file char
	eol = ":"

	' Remove inline comment (must be before whitespace striping)
	line = inline_comment(line)

	' Remove leading and trailing whitespaces: null, horizontal tab, line feed,
	' vertical tab, form feed, carriage return, space
	line = strip(line)

	' Remove comments except inline ones (must be after whitespace striping)
	If Mid(line, 1, 1) = "'" Or UCase(Mid(line, 1, 3)) = "REM" Then
		line = ""
	End If

	' Remove space when several spaces between two keywords
	line = internal_space(line)

	' Remove line splitting
	If Right(line, 2) = " _" Then
		line = Left(line, Len(line) - 1)
		eol = ""
	End If

	If line <> "" Then
		line = line & eol
	End If

	minify_line = line
End Function

' Remove inline comments
' In VBS there is no single quote strings so it's safe to remove until the end
' of string when ecountering a single quote.
' The only case to handle if is a single quote appears in a double quote string.
Function inline_comment(line)
	Dim quotes, i, c

	' For each single quote, if there is an odd number of double quote before
	' we are in a string, but if there is an even number of double quote before
	' we are out of a string so this is an inline comment and we can remove all
	' that comes after.
	quotes = 0
	For i = 1 To Len(line)
		c = Mid(line, i, 1)
		If c = Chr(34) Then
			quotes = quotes + 1
		End If
		If c = "'" And quotes Mod 2 = 0 Then
			inline_comment = Mid(line, 1, i - 1)
			Exit Function
		End If
	Next

	inline_comment = line
End Function

' Remove all the characters supposed to be whitespaces
Function strip(line)
	Dim re

	set re = New RegExp
	re.Pattern = "^[\t\r\n\f\v ]*|[\t\r\n\f\v ]*$"
	re.Global = True

	strip = re.Replace(line, "")
End Function

' Remove extra spaces (several spaces between two keywords except in a string)
' More reliable than internal_space_old which use string replacement and string
' split
Function internal_space(line)
	Dim quotes, prev, i, c, result

	' For each single quote, if there is an odd number of double quote before
	' we are in a string, but if there is an even number of double quote before
	' we are out of a string.
	quotes = 0
	prev = ""

	result = ""

	For i = 1 To Len(line)
		c = Mid(line, i, 1)
		If c = Chr(34) Then
			quotes = quotes + 1
		End If
		If Not ( prev = " " And c = " " And quotes Mod 2 = 0 ) Then
			result = result & c
		End If
		prev = c
	Next

	internal_space = result
End Function

text = WScript.StdIn.ReadAll()
text = minify(text)
WScript.StdOut.Write(text)
( 2 * b ) || ! ( 2 * b )