ঠিকানা 0000000C একটি বিশেষ ঠিকানা?


32

প্রোগ্রামিং যখন কখনও কখনও জিনিস বিরতি। আপনি একটি ভুল করেছেন এবং আপনার প্রোগ্রামটি একটি ভুল ঠিকানা থেকে পড়ার চেষ্টা করে।

একটি জিনিস যা আমার কাছে দাঁড়ায় যে প্রায়শই এই ব্যতিক্রমগুলি হ'ল:

Access violation at address 012D37BC in module 'myprog.exe'. Read of address 0000000C.

এখন আমি অনেকগুলি ত্রুটিযুক্ত লগ দেখতে পাচ্ছি এবং আমার কাছে যা দাঁড়ায় তা হ'ল: 0000000C। এটি কি "বিশেষ" ঠিকানা? আমি খারাপ পাঠ সহ অন্যান্য অ্যাক্সেস লঙ্ঘন দেখতে পাচ্ছি তবে ঠিকানাগুলি কেবল এলোমেলো মনে হচ্ছে তবে এটি সম্পূর্ণ ভিন্ন পরিস্থিতিতে ফিরে আসতে থাকে।


1
আমিও লক্ষ্য করেছি যে 0000000Cহয় পথ চেয়ে বেশি প্রচলিত 00000008, কিন্তু উত্তর কেউই ঠিকানা বলে মনে হচ্ছে যে এ সব: /
গরুর হাঁসের

2
সম্ভবত যে System.Runtime.CompilerServices.RuntimeHelpers.OffsetToStringDataহয় 12=0x0Cকেন এই অফসেট বেশি দেখা যায় একটি কারণ আছে।
মার্ক হার্ট

1
পছন্দ করেছেন আপনি কি সত্যিই ভাবেন যে এতগুলি নিয়ন্ত্রিত অ্যাপ্লিকেশন রয়েছে যা উদ্দেশ্যমূলকভাবে .NET স্ট্রিংগুলি পড়তে / লিখতে পারে যে এটি অ্যাক্সেস লঙ্ঘনের একটি প্রধান উত্স হবে?
লুয়ান

উত্তর:


57

00000000একটি বিশেষ ঠিকানা (নাল পয়েন্টার)। 0000000Cআপনি যখন নাল পয়েন্টারে 12 এর অফসেট যুক্ত করেন তখনই আপনি যা পান তা সম্ভবত সম্ভবত কেউ zনীচের মত একটি কাঠামোর সদস্য হিসাবে চেষ্টা করার চেষ্টা করেছিলেন যা আসলে নাল ছিল।

struct Foo {
    int w, x, y; // or anything else that takes 12 bytes including padding
    // such as: uint64_t w; char x;
    // or: void *w; char padding[8];
    // all assuming an ordinary 32 bit x86 system
    int z;
}

29
বা হতে পারে কারণ কিছু ছোট অবিচ্ছেদ্য মান ভুল করে বিবেচনা করা হয়েছিল যেন এটি পয়েন্টার। ছোট মানগুলি বিশাল মানগুলির তুলনায় অনেক বেশি সাধারণ, সুতরাং এটি 0X0000000C এর চেয়ে 0x43FCC893 এর পরিবর্তে 0X0000000C এর মতো অবৈধ ঠিকানা তৈরি করে।
কিলিয়ান ফট

3
আমি এই প্রশ্নটি জিজ্ঞাসা করার কারণটি হ'ল 0000000C অন্যান্য অ্যাড্রেসগুলির তুলনায় প্রায়শই ফিরে আসে। কেন অফসেট 12 এর মাত্রা আরও সাধারণ হয় তবে 4, 8 বা 16 অফসেট হয়?
পিটার বি

5
আরও তদন্তের পরে এই উত্তরটি সম্পূর্ণ সঠিক। আমার উত্সে ক্লাসগুলির "ট্যাগ" সম্পত্তিটি ব্যাপকভাবে ব্যবহৃত হয় (ভাল বা খারাপ আমাকে এটি মোকাবেলা করতে হবে)) আমার ক্ষেত্রে ট্যাগ সম্পত্তিটি নিম্ন স্তরের বেস শ্রেণীর একটি অংশ এবং এটি সর্বদা অফসেটে তৈরি হয়েছিল।
পিটার বি

1
দুর্দান্ত পয়েন্ট। সম্ভবত নাল পয়েন্টার কেসটি আচ্ছাদিত ছিল তবে নাল পয়েন্টার ++ কেবলমাত্র একটি সাধারণ (এবং এই ক্ষেত্রে অবৈধ) ঠিকানা, সুতরাং এটি কেবল এটি অ্যাক্সেস করার পরে ব্যর্থ হয়।
নিল

8
@ লুশেনকো হ্যাঁ, মেমরির সুরক্ষা সাধারণত পুরো পৃষ্ঠাগুলিতে কাজ করে, এবং কেবল 0 ধরা সম্ভব হলেও নীচের ঠিকানাগুলি সুরক্ষা দেওয়াও ভাল rable কারণ নাল পয়েন্টারযুক্ত পয়েন্টার গাণিতিক ঘটলে তারা প্রবেশ করার সম্ভাবনা রয়েছে (যেমন রয়েছে ওপির ক্ষেত্রে)।

11

উইন্ডোজ এটি dereference করা বেআইনী সমগ্র প্রথম ও শেষ পৃষ্ঠা , অন্য কথায় প্রক্রিয়া মেমরি প্রথম অথবা শেষ 64 KiB (রেঞ্জ 0x00000000থেকে 0x0000ffffএবং 0xffff0000থেকে 0xffffffffএকটি 32 বিট অ্যাপ্লিকেশনের মধ্যে)।

এটি নাল পয়েন্টার বা সূচককে একটি নাল অ্যারেতে ডিফারেন্স করার অপরিজ্ঞাত আচরণকে ফাঁদে ফেলতে হয়। এবং পৃষ্ঠার আকার Ki৪ কিবি তাই উইন্ডোজকে কেবলমাত্র প্রথম বা শেষ পৃষ্ঠাকে একটি বৈধ ব্যাপ্তি বরাদ্দ করা উচিত।

এটি অস্বীকৃতিযুক্ত পয়েন্টারগুলির বিরুদ্ধে রক্ষা করবে না যার কোনও মান থাকতে পারে (বৈধ ঠিকানা সহ)।


7
উইন্ডোজ সত্যিই এটি করতে পারে না। পৃষ্ঠার টেবিলটি এমন কাঠামো যা x86 দ্বারা সংজ্ঞায়িত এবং প্রয়োজনীয় এবং ছোট পৃষ্ঠাগুলি 4KB এ স্থির করা হয়। এটি প্রস্তর স্থাপন করা হয়েছে (আরও সুনির্দিষ্টভাবে সিলিকনে)। 64KB সম্ভবত সুবিধার জন্য।
এল্ডারবাগ

12
এই ক্ষেত্রে আমি 65 কেবি এর পরিবর্তে 64 কিবি লিখব, যেহেতু পাওয়ার-টু মাপটি প্রাসঙ্গিক।
কোডসইনচওস

4
K৪ কেবি পরিসীমা এনটি-র অ্যাপ্লা সংস্করণ থেকে একটি বাম দিকে। এবং এটি পৃষ্ঠার আকার নয়, বরাদ্দ গ্রানুলারিটি। ব্লগস.এমএসএন
বি /

3
@ কোডসইনচওস: বড় হাতের "এম", "জি", এবং "টি" দ্বিধাহীন হলেও আমি 10 k 3 এর জন্য "কে" এবং 2 কে 10 এর জন্য "কে" ব্যবহারকে অবমূল্যায়নের কোনও কারণ দেখতে পাচ্ছি না।
সুপারক্যাট

2
@ মুভিংডাক হ্যাঁ সত্যই, তাই আমি ছোট পাতাগুলি সংশোধন করেছি। বেশিরভাগ x64 সিপিইউ 1 জিআইবি পৃষ্ঠাগুলি সমর্থন করে। যতদূর আমি জানি, উইন্ডোজ সর্বদা 4KB পৃষ্ঠাগুলি সহ পৃষ্ঠাগুলি রাখে, যদি না বিশেষ API এর সাথে বরাদ্দ থাকে।
বয়স্কবাগ

2

তবে কেন এটি 0x0Cসাধারণ হিসাবে মনে 0x08হয় (এটি কি সত্য? আমি জানি না; এবং কী ধরণের অ্যাপ্লিকেশনগুলিতে?), এটি ভার্চুয়াল পদ্ধতিতে টেবিল পয়েন্টারগুলির সাথে করতে পারে। এটি সত্যিই একটি মন্তব্য (বুনো গণ অনুমান করা :), তবে এটি কিছুটা বড়, সুতরাং এখানে যায় ... যদি আপনি ভার্চুয়াল পদ্ধতিগুলির সাথে একটি ক্লাস পেয়ে থাকেন তবে তার নিজস্ব ক্ষেত্রগুলি স্থানান্তরিত হতে চলেছে 0x04। উদাহরণস্বরূপ, অন্য একটি ভার্চুয়াল শ্রেণীর উত্তরাধিকার সূত্রে এমন শ্রেণীর মেমরি বিন্যাস থাকতে পারে:

0x00 - VMT pointer for parent
0x04 - Field 1 in parent
0x08 - VMT pointer for child
0x0C - Field 1 in child

এটি কি সাধারণ দৃশ্য, না কাছাকাছি? আমি নিশ্চিত নই. তবে মনে রাখবেন যে 64৪-বিট অ্যাপ্লিকেশনটিতে এটি আরও আকর্ষণীয়ভাবে 0x0Cমানটির দিকে সরে যেতে পারে:

0x00 - VMT parent
0x08 - Field 1 parent
0x0C - VMT child
0x14 - Field 2 child

সুতরাং আসলে অনেকগুলি ক্ষেত্রেই অ্যাপ্লিকেশনগুলির নাল-পয়েন্টার অফসেটগুলিতে উল্লেখযোগ্য ওভারল্যাপ থাকতে পারে। এটি কোনও শিশু শ্রেণির প্রথম ক্ষেত্র, বা এর ভার্চুয়াল পদ্ধতি সারণী পয়েন্টার হতে পারে - যখনই আপনি কোনও ভার্চুয়াল পদ্ধতি কল করেন যখনই আপনি কোনও পয়েন্টারে ভার্চুয়াল পদ্ধতিটি কল করছেন null, আপনি তার অ্যাক্সেস লঙ্ঘন পাবেন ভিএমটি অফসেট। এই নির্দিষ্ট মানটির প্রসারটি তখন কিছু সাধারণ এপিআইর সাথে কিছু করতে পারে যা একটি বর্গ সরবরাহ করে যা একই ধরণের উত্তরাধিকারের ধরণ রয়েছে, বা সম্ভবত আরও একটি বিশেষ ইন্টারফেস (কিছু শ্রেণীর অ্যাপ্লিকেশন যেমন ডাইরেক্টএক্স গেমগুলির পক্ষে যথেষ্ট সম্ভব) সরবরাহ করে। এটির মতো সাধারণ কিছু সাধারণ কারণগুলি ট্র্যাক করা সম্ভব হতে পারে তবে আমি এমন অ্যাপ্লিকেশনগুলি থেকে খুব দ্রুত মুক্তি পেতে চাই যা এলোমেলোভাবে হয় so


1
আপনি যদি মন্তব্যগুলি সন্ধান করেন তবে অনুমানটি যথেষ্ট পরিমাণে হ্রাস করতে পারেন।
13-28

@ ডিডুকিপ্লেটার ওয়েল, আমি ধারণাটি পেয়েছি যে ম্যানেজড .NET স্ট্রিংগুলি ম্যানুয়াল পয়েন্টার অপারেশনগুলি ভীতিজনক সহ সুরক্ষিত সুরক্ষিত কোডে ব্যবহার করা হয়, এবং এই ভেবে যে আরও বেশি অ্যাক্সেস লঙ্ঘনের এটিই প্রধান কারণ হবে thought "হ্যাঁ, এটি পুরোপুরি মেমরি নিরাপদ, চিন্তা করবেন না, আমরা সি # ব্যবহার করেছি C
লুয়ান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.