PDA

View Full Version : گفتگو: تبدیل کدهای Assembly به Shell Code در دلفی



بهروز عباسی
دوشنبه 03 تیر 1392, 23:17 عصر
درود به همه
خسته نباشید .
بازم یه کار عجیب دارم:شیطان:

من دارم یه تابع برای ساخت Shell Code مینویسم چندتای مشکل دارم :


چرا این تابع (فعلاً تا همینجای کار) هم درست کار میکنه و هم اشتباه.



چطوری یک/مجموعه دستورات زبان Assembly رو به صورت یک پارامتر رشته ای به تابع پاس بدم و توی تابع اونو به صورت Inline Assembly دربیارم.

این تابعی که نوشتم :
(*
uses
System.StrUtils; *)
function ASM2Sh3lc0de: String;
type
TOpCode = array of Byte;
var
_Result: AnsiString;

function ASM2Opcode: TOpCode;
var
_Begin, _End: Pointer;
begin
ASM
LEA EAX, @@Begin
MOV _Begin, EAX
LEA EAX, @@end
MOV _End, EAX
JMP @@end
@@Begin:
(* --| Begin |-- *)

XOR EAX,EAX
POP EDX
POP ECX


(* --| End |-- *)
@@end:
end;
SetLength(Result, Integer(DWORD(_End) - DWORD(_Begin)));
Move(_Begin^, Pointer(Result)^, Length(Result));
end;

var
i: Integer;
begin
for i := 0 to High(ASM2Opcode) do
begin
_Result := _Result + (Format('$%X,', [ASM2Opcode[i]]));
end;
if RightStr(_Result, 1) = ',' then
_Result := LeftStr(_Result, Length(_Result) - 1);

Result := 'Const ShellCode:Array[0..' + IntToStr(High(ASM2Opcode)) + '] of byte = (' +
_Result + ');';
end;


این نتیجه حاصل از یک برنامه جا افتاده:قهقهه: :

106125


این هم نتیجه برنامه من برای همون دستورات Assembly :

106128
تا اینجا سوال اول من بود ،همون طور که توی تصاویر مشاهده میکنید چند دستور درسته و چندتا ...

سوال بعدی ؛اگه بخوام تابع رو به این صورت بنویسم باید چکار کنم ،اصلاً میشه ؟
(*
uses
System.StrUtils; *)
function ASM2Sh3lc0de(AInstruction: AnsiString): String;
type
TOpCode = array of Byte;
var
_Result: AnsiString;

function ASM2Opcode: TOpCode;
var
_Begin, _End: Pointer;
begin
ASM
LEA EAX, @@Begin
MOV _Begin, EAX
LEA EAX, @@end
MOV _End, EAX
JMP @@end
@@Begin:
(* --| Begin |-- *)

AInstruction

(* --| End |-- *)
@@end:
end;
SetLength(Result, Integer(DWORD(_End) - DWORD(_Begin)));
Move(_Begin^, Pointer(Result)^, Length(Result));
end;

var
i: Integer;
begin
for i := 0 to High(ASM2Opcode) do
begin
_Result := _Result + (Format('$%X,', [ASM2Opcode[i]]));
end;
if RightStr(_Result, 1) = ',' then
_Result := LeftStr(_Result, Length(_Result) - 1);

Result := 'Const ShellCode:Array[0..' + IntToStr(High(ASM2Opcode)) + '] of byte = (' +
_Result + ');';
end;

و مثلا اینطوری فراخوانیش کنم :
ASM2Sh3lc0de('XOR EAX,EAX')

با تشکر از همه.:لبخند:

arash_ebrahimi_nk
سه شنبه 04 تیر 1392, 06:30 صبح
سلام دوست عزیز

کُد نویسی که شما میخواهید در بخش دوم انجام بدید با کاری که توی مورد اول انجام دادید خیلی تفاوت داره...
در مورد اول شما کُدی که توی برنامه شما نوشته شده و کامپایل میشه و OpCode اون ساخته میشه رو در درست دارید و به راحتی بایت های موجود رو به رشته تبدیل میکنید و به کاربر تحویل میدید.
اما مورد دوم نیازمند داشتن یک parser و یک disassembler هست که کار رو کمی سخت میکنه. یعنی اول باید تشخیص بدید که رشته چه instruction ای هست و بعد اون instruction رو به disassembler بدید تا اون رو به درستی معنی کنه و بعد بایت های حاصل رو به عنوان نتیجه برگردونید.
نظر من اینه که: کاربرد شل کُد چیزی نیست که بخواهید براش برنامه ای مثل این بنویسید....

موفق باشید.

یوسف زالی
سه شنبه 04 تیر 1392, 09:00 صبح
در مورد دوم می شه با کمک RemObjects انجامش داد.
توضیحات بیشتر = برادر شاهین عشایری D;

بهروز عباسی
سه شنبه 04 تیر 1392, 09:54 صبح
مورد دوم نیازمند داشتن یک parser و یک disassembler هست که کار رو کمی سخت میکنه. یعنی اول باید تشخیص بدید که رشته چه instruction ای هست و بعد اون instruction رو به disassembler بدید تا اون رو به درستی معنی کنه و بعد بایت های حاصل رو به عنوان نتیجه برگردونید.حرف شما درسته بدون این کارها نمیشه ؟ ،چون تاجایی که من دیدم Lib های که برای DisASM کردن توی دلفی موجوده اول آمدن دستورات برنامه رو به صورت Opcode میخونن و با استفاده از معادل اون در ASM اونو به Instruction های Assembly تبدیل میکنن واین عکس چیزی که من می خوام
فکر کنم منظور شما چیزی عکس Disassembler باشه ؛در این صورت اول باید یک Parser و یک Assembler بنویسم ! که در این حالت هم باید عکس Disassembler عمل کنم یعنی Opcpde تمام Instruction ها رو داشته باشم (که میشه از مستندات Intel گیر آورد) بعد دونه دونه Instruction ها رو به Opcode تبدیل کنم . خودم به این مورد فکر کردم ولی خیلی طولانی و ... میشه من دنبال یک روش پویا هستم.


نظر من اینه که: کاربرد شل کُد چیزی نیست که بخواهید براش برنامه ای مثل این بنویسید....اینو میدونم هدف اصلی من هم تولید shell code نیست ،کاردیگه ای دارم:شیطان:
باید در زمان اجرا یکسری کدها رو به Opcpde تبدیل کنم و اون Opcpdeها رو به جای تزریق کنم:کف: ،چون دیدم کاربردش به shell code نزدیکه سوال رو اینطوری مطرح کردم.

Felony
سه شنبه 04 تیر 1392, 18:29 عصر
این نتیجه حاصل از یک برنامه جا افتاده :
http://barnamenevis.org/attachment.php?attachmentid=106125&d=1372101064

این هم نتیجه برنامه من برای همون دستورات Assembly :
http://barnamenevis.org/attachment.php?attachmentid=106128&d=1372101772

خوب ؟! مشکل کجاست ؟!
Opcode تولیدی برای XOR در پردازنده 32 بیتی میتونه از 30 تا 33 بسته به دستورات متفاوت باشه ، کد شما درست عمل میکنه ، کدی که Olly تولید میکنه هم درست عمل میکنه ، مرجع opcode شما همیشه باید Intel x86 Assembler Instruction Set Opcode Table (http://sparksandflames.com/files/x86InstructionChart.html) باشه نه Olly و ...

برای اطمینان تو همون Olly دستور XOR EAX,EAX رو گیر بیارید و روش کلیک راست کنید و از منوی Binary زیرشاخه Edit روانتخاب کنید ، حالا تو قسمت Hex+00 اون Opcode که مقدارش 33 هست رو با 31 جایگزین کنید و نتیجه حاصل رو بررسی کنید :)

این رو هم ببین تا بفهمی XOR ها چرا فرق دارن : http://ref.x86asm.net/coder32.html

البته ریزکاری های دیگه ای هم این وسط مطرح میشه ( Null Byte و ... ) که اینجا جاش نیست ...

arash_ebrahimi_nk
سه شنبه 04 تیر 1392, 20:40 عصر
حرف شما درسته بدون این کارها نمیشه ؟ ،چون تاجایی که من دیدم Lib های که برای DisASM کردن توی دلفی موجوده اول آمدن دستورات برنامه رو به صورت Opcode میخونن و با استفاده از معادل اون در ASM اونو به Instruction های Assembly تبدیل میکنن واین عکس چیزی که من می خوام
فکر کنم منظور شما چیزی عکس Disassembler باشه ؛در این صورت اول باید یک Parser و یک Assembler بنویسم ! که در این حالت هم باید عکس Disassembler عمل کنم یعنی Opcpde تمام Instruction ها رو داشته باشم (که میشه از مستندات Intel گیر آورد) بعد دونه دونه Instruction ها رو به Opcode تبدیل کنم . خودم به این مورد فکر کردم ولی خیلی طولانی و ... میشه من دنبال یک روش پویا هستم.

اینو میدونم هدف اصلی من هم تولید shell code نیست ،کاردیگه ای دارم:شیطان:
باید در زمان اجرا یکسری کدها رو به Opcpde تبدیل کنم و اون Opcpdeها رو به جای تزریق کنم:کف: ،چون دیدم کاربردش به shell code نزدیکه سوال رو اینطوری مطرح کردم.

اگه میخواهید بخشی از کُدها رو به یک بخش دیگه کُدهاتون تزریق کنید باید با دقت عمل کنید و کار رو دستی انجام بدید این نظر منه.
ولی پیشنهادم اینه که شما یه پروسیجر کامل بنویسید و به دلفی اجازه بدید اون رو کامپایل کنه و اونوقت کل کُد کامپایل شده رو بطور کامل در بخش مورد نظر (با استفاده از یک call) استفاده بکنید.
امیدوارم متوجه منظورم شده باشید.
موفق باشید.