PDA

View Full Version : Error in pointer



V0RTEX
دوشنبه 07 فروردین 1391, 12:00 عصر
سلام
من می خوام به صورت مستقیم یه pointer رو مقدار دهی کنم ولی برنامه error میده آیا راهی هست که بشه این کار رو کرد مثل این کد:
#include <iostream>
using namespace std;
int main()
{
int *ptr=(int *)0x67;
int p=*ptr;
cout << p << endl;
system("pause");
return 0;
}


که وقتی اجراش می کنم این error رو میده

Unhandled exception at 0x013213f8 in test.exe: 0xC0000005: Access violation reading location 0x00000067.


من از VS 2010 sp1 استفاده می کنم و Windows 7 sp1

Arcsinos
دوشنبه 07 فروردین 1391, 14:37 عصر
( پیشاپیش از geek1982 عذر خواهی می کنم :لبخند:) سلام دوست عزیز فکر میکنم چون شما می خوایید به دو گیگ حافظه مجازی پایین دسترسی پیدا کنید با یه همچین خطایی رو به رو میشید (البته مطمئن نیستم) . میدونی که هر PE میتونه چهار گیگ رو آدرس دهی کنه . دو گیگ پایین از 0X00000000 تا 0x7FFFFFFF فضای مُدِ هسته (Kernel Mode Space) که فقط سیستم عامل بهش دست رسی داره و اگه تو هم میخوای دسترسی داشته باشی باید توی Kernel Mode کد بنویسی و دو گیگ بالا از آدرس 0x80000000 تا 0xFFFFFFFF فضای مُدِ کاربر هستش که میتونی بهش دسترسی داشته باشی و سیستم عامل هم هیچ کاری باهات نداره . همین برنامه ات رو با یه آدرس دیگه امتحان کن (من کردم) جواب میده.

من این برنامه رو دیباگش کردم مثل اینکه (EP(Entry Point این برنامه یه مقدار مشکل داره و از آدرس 0x77B40194 شروع میشه . برای اینکه برنامه درست کار کنه این آدرس رو بهش بده . (من تا حالا چنین چیزی ندیده بودم که امروز دیدم) . البته با آدرس های دیگه هم کار میکنه ها، ولی چون برنامه خیلی کوچیکه سعی کن آدرس هات دو رو بر همین آدرس باشن یعنی آدرس 0x77B40194 . اگه مثلا بدی 0x845E2B00 جواب نمیده و باز هم با خطا رو به رو میشی .(چون این آدرس خارج از محدوده ی PE هست.) سعی کن از رِنج 0x77B40000 تا 0x77C00000 بدی.
موفق و پیروز باشی

V0RTEX
دوشنبه 07 فروردین 1391, 18:23 عصر
دقیقا من هم می خوام به kernel space و یا هر جای دیگه ی ram دسترسی داشته باشم... ولی حتی با assembly هم نشد
این کد assembly رو یه نگاه کنید
#include <iostream>
using namespace std;
int main()
{
int p=0;
int address=(int)&p;
int bdaddress=0x64;//address_in_bad_location
cout << p << endl;
__asm
{
push eax
push ebx
;-------------------
mov eax,[address] ;eax=&p
mov ebx,[bdaddress] ;ebx=0x64
mov ebx,[ebx] ;ebx=the value in 0x64 <-- error
mov [eax],ebx ;p=ebx
;-----------------
pop ebx
pop eax
}
cout << p << endl;
system("pause");
return 0;
}
این کد باید بتونه مقداری که در آدرس bdadress هست رو توی p بریزه ولی به mov ebx,[ebx]
که می رسه همون error قبلی رو میده

Unhandled exception at 0x00b6143a in test.exe: 0xC0000005: Access violation reading location 0x00000064.

pe32_64
دوشنبه 07 فروردین 1391, 18:38 عصر
این کاری که شما میخوای بکنی در یک برنامه کاملا ممنوع هست.

V0RTEX
دوشنبه 07 فروردین 1391, 18:40 عصر
بله خودم هم می دونم ممنوعه ولی همین جور که خوده OS می تونه این کار رو انجام بده پس ما هم باید بتونم
یعنی یه راهی برای این کار باید وجود داشته باشه حالا چه مستقیم چه غیر مستقیم

V0RTEX
دوشنبه 07 فروردین 1391, 20:02 عصر
با تشکر از همه من خودم یه راه پیدا کردم
البته هنوز تستش نکردم (چون خطرناکه):متفکر:
برای این کار باید تو assembly از interrupt 2Fh استفاده کرد
اگه کسی قبلا تو این کار تجربه داره plz بگه که الکی کامپیوتر رو نترکونیم:لبخند:

Arcsinos
دوشنبه 07 فروردین 1391, 22:12 عصر
دقیقا من هم می خوام به kernel space و یا هر جای دیگه ی ram دسترسی داشته باشم... .
سلام دوست عزیز، شما که به هیچ عنوان نمیتونی به هر جایی از RAM دسترسی داشته باشی . این آدرسی هم که داری میدی در واقع آدرس مجازی هست نه یه آدرس فیزیکی .


ولی همین جور که خوده OS می تونه این کار رو انجام بده پس ما هم باید بتونم
به نظر من که OS هم نمیتونه همچین کاریو کنه، OS فقط میاد آدرسهای مجازی رو توسط Page Table به آدرس فیزیکی تبدیل میکنه ولا غیر (و احتمالا چون توی Page Table نمیتونه اون آدرس مجازی (0x67) رو به آدرس فیزیکی تبدیل کنه اون ارور رو میده. چون اگه دقت کنی با آدرس هایی که بالا بهت گفتم هیچ مشکلی نداره مثلا آدرس EP)


اگه کسی قبلا تو این کار تجربه داره plz بگه که الکی کامپیوتر رو نترکونیم
اگه تو ویندوز داری این کارو انجام می دی، هیچ اتفاقی نمیوفته فقط احتمالا با یه Blue Screen مواجه میشی که باز همین (اگه نذاری سیستم Reset بشه ) خطای 0x00000005 رو بهت نشون خواهد داد (که بعید می دونم با Blue Screen مواجه بشی ، احتمالا همون خطایی که قبلا میداد رو بده، Blue Screen بیشتر توی کرنل مد دیده میشه تا یوزر مد)

و در آخر یه سوالی داشتم و اونم اینه که میشه دلیل این کارتو به ما هم بگی ؟ :لبخند: من هنوز نمیدونم واسه چی میخوای این کارو انجام بدی .

موفق و موید در پناه خداوند یکتا

حامد مصافی
دوشنبه 07 فروردین 1391, 23:47 عصر
اگه کسی قبلا تو این کار تجربه داره plz بگه که الکی کامپیوتر رو نترکونیم:لبخند:
یک نرم‌افزار مجازی سازی مانند VirtualBox نصب کنید و روی یک سیستم‌عامل مجازی هرچیزی که می‌خوای تست کن.

V0RTEX
سه شنبه 08 فروردین 1391, 17:49 عصر
کار نشد نداره
این هم از راه و روش :متفکر:
http://www.codeproject.com/Articles/45788/The-Real-Protected-Long-mode-assembly-tutorial-for


In real mode, the segment registers (CS, DS, ES, SS, FS, GS) specify a real mode segment. And you can put anything to them, no matter where it points. And you can read and write and execute from that segment.

Arcsinos
جمعه 11 فروردین 1391, 11:38 صبح
با سلام دوستان عزیز


In real mode, the segment registers (CS, DS, ES, SS, FS, GS) specify a real mode segment. And you can put anything to them, no matter where it points

ترجمه : در مُدِ حقیقی، ثبات های سگمنت (CS,DS,ES,SS,FS,GS) یک سگمنتِ مُدِ حقیقی را مشخص می کنند و شما می توانید در داخل آنها هر چیزی قرار دهید و مهم نیست که به کجا اشاره می کنند.(آدرس : نوشه ی Dear VORTEX)

این داره میگه مُدِ حقیقی نه مُدِ حفاظت شده . یکی از وظایفِ سیستم عامل اینه که از حافظه محافظت کنه ( Memory Protection) و وقتی که میخواد از حافظه محافظت کنه در یک حالتی کار می کنه به نام Protected Mode که فارسیش میشه مُدِ محافظت شده و شما نمیتونی کاری انجام بدی یا به قولی به هر جایی که میخوای اشاره کنی (آدرس (http://www.brokenthorn.com/Resources/OSDev0.html)). تنها با استفاده از (Dynamic Memory Allocation) یعنی توابع ()malloc و ()free در زبان C و یا عملگرهای Delete و new در ++C به قسمت هایی از حافظه دسترسی پیدا کنی و این توابع و عملگر ها توسط سیستم عامل کنترول میشن که گفتم محافظت شده است.
حالا وقتی میخوای توی Real Mode از این توابع استفاده کنی، نمی تونی (چون وظیفه ی سیستم عامل بود که کارای مربوط به این توابع که اختصاص و پاک سازی حافظه بود رو انجام بده) . توی Real Mode در واقع خود برنامه باید کارای این توابع رو انجام بده یا به قولی خود برنامه یه سیستم عامل باشه که خوب برنامه نویس نمیاد کلی وقت بذاره این توابع رو از نو تعریف کنه و به قولی یه برنامه برای مدیریت حافظه (Memory Management) بنویسه و مجبوره مستقیما به خونه های حافظه اشاره کنه. اونوقته که میتونی با یه اشاره گرِ وحشی (Wild Pointer) به هر جا که عشقت می کشه اشاره کنی (آدرس (http://www.brokenthorn.com/Resources/OSDev2.html)) . به عنوان مثال :


char* pointer = (char*)0x5000

لینکی هم که داده بودند (در بالا) رو خوندم که اونجا هم باز همین حرف ها رو تایید می کنه .


In Real mode, everything is 16 bits.

ترجمه : در مد حقیقی همه چیز 16 بیتی است . (آدرس (http://www.codeproject.com/Articles/45788/The-Real-Protected-Long-mode-assembly-tutorial-for))
حالا چطور میشه با این 16 بیت به 4 گیگا بایتِ مختلف اشاره کرد (اللهُ اعلم) (البته من نمیگم دوست عزیزمون VORTEX میگن که کار نشد نداره). با 16 بیت فقط میشه به 64 کیلو بایتِ مختلف اشاره کرد و به همین خاطره که سگمنت های برنامه از جمله سگمت کد، سگمنت داده و سگمنت پشته حد اکثر می تونن 64KB باشن . که مدل Huge از 64KB حافظه استفاده می کنه.


In 32-bit protected Mode a segment can have any size, from 1 byte to 4GB. The OS defines the size of each segment, and now each segment can have limitations (read, write, execute on or off).

ترجمه : در مد حافظت شده ی 32 بیتی، یک سگمنت می تواند هر اندازه ای از 1 بایت تا 4 گیگا بایت داشته باشد . این سیستم عامل است که اندازه ی هر سگمنت را تعیین می کند و مشخص می کند که هر سگمت چه محدودیت هایی (خواندن، نوشتن، اجرا) می تواند داشته باشد . (آدرس (http://www.codeproject.com/Articles/45788/The-Real-Protected-Long-mode-assembly-tutorial-for))
نکته اینکه وقتی صحبت از سیستم عامل میشه بحث مد حفاظت شده هم پیش میاد و وقتی که بحث حفاظت شده میشه بحث سیستم عامل پیش میاد .

Note: If you switch processor modes, the IVT will not be avilable.
ترجمه : نکته : اگر شما مد پردازنده را عوض کنید دیگر قادر به استفاده از IVT نخواهید بود .(آدرس (http://www.brokenthorn.com/Resources/OSDev3.html))
یعنی اینکه اگه ما از Real Mode به Protected Mode سوئیچ کنیم دیگه نمی تونیم از IVT یا همون Interrupt Vector Table یعنی جدول وقفه های BIOS چه وقفه های نرم افزاری چه وقفه های سخت افزای استفاده کنیم که در OSهای 32 بیتی اینچنین است .
ولی باز هم شاید به قول دوست عزیزمون VORTEX کار نشد نداشته باشه . منتهی میخواستم یه لطفی کنید که اگه تونستید در سیستم عامل به هر نقطه از Physical Memory اشاره کنید، حتما کد برنامتون رو در اختیار ما هم قرار بدید تا استفاده کنیم.(هم اکنون نیازمند یاریِ سبزتان هستیم :لبخند:)

موفق و پیروز در پناه حق

V0RTEX
یک شنبه 13 فروردین 1391, 01:44 صبح
آقا فقط یه سوال فنی مهندسی
چه طوری وقتی که ما تو ring3 هستیم میشه دستوراتی که تو ring3 قابل دسترسی نیست دست رسی داشت
مثلا
__asm
{
in al, 0x92
or al, 2
out 0x92, al
}

چون وقتی که این کد رو اجرا می کنیم VS می گه:
0xC0000096: Privileged instruction.
یا حتی وقتی که من می خوام از interrupt های BIOS استفاده کنم مثلا:
__asm
{
mov ax, 0x2401
int 0x15
}
می گه :
0xC0000005: Access violation reading location 0xffffffff.

اگر این مشکل ها حل بشه یک کار هایی میشه کرد
چون میشه اول بریم تو real mode بعدش آدرس مورد نظر رو بخوانیم و یا بنویسیم بعدش باز برگردیم به protected mode
یه جورایی مثل unreal mode فقط برعکسش:متفکر:


من فقط این کار رو برای این می خوام انجام بدم که یاد بگیرم
حالا من یه کد دیدم دیدم جالب گفتم attach کنم علاقه مندان استفاده کنند :لبخندساده:
85013

V0RTEX
دوشنبه 14 فروردین 1391, 20:28 عصر
یکی کمک کنه plz