2011-09-11 17 views
5

Sau khi Rebasing chương trình chính rất cao trong cơ sở hình ảnh riêng của nó.C++ Cách kiểm soát cơ sở hình ảnh của API LoadLibrary

Làm thế nào để đảm bảo rằng các dll đó được nạp sẽ được tải trong 0x400000

dllImageBase = LoadLibrary("test.dll"); 
printf("imagebase = 0x%x", dllImageBase); 

Tôi luôn luôn có được 0x460000 thay vì 0x400000

tôi cần hướng dẫn đầu tiên dll của tôi bắt đầu từ 0x401000, nó được sử dụng để bắt đầu từ 0x600000 trước rebasing

lệnh cho mối liên kết để rebase là

#pragma comment(linker, "/BASE:8000000") 

Vì vậy, 0x400000 thực sự là miễn phí ngay bây giờ nhưng nó không sử dụng nó theo mặc định .. vì vậy bất kỳ cách nào tôi có thể kiểm soát nó, nơi nó sẽ di dời. Một số WIN32API có thể?

+0

Làm thế nào để bạn biết '0x400000' là miễn phí? Một số DLL khác có thể ở đó. –

+0

Tôi nhìn vào bản đồ bộ nhớ và tiêu đề .code/PE của chương trình bắt đầu tại '0x8000000' .. và trước khi nó là' 0x3300000' chỉ là sortbls.nls và nó chỉ tiếp tục thấp hơn và không có gì thực sự đang sử dụng '0x4000000'. Nhưng những gì bạn đang nói một nơi nào đó trong tương lai nó sẽ phá vỡ bởi một số tai nạn quái dị yeah? thats nếu tôi con số nó ra làm thế nào để thiết lập quá 0x4000000. Sau đó, một lần nữa nếu tôi bằng cách nào đó tìm ra cách để kiểm soát này, họ sẽ không bao giờ tải có một lần nữa – SSpoke

+0

Tôi không biết bất kỳ cách nào để kiểm soát điều đó. Nếu mã của bạn phụ thuộc vào một DLL cụ thể sống tại một địa chỉ cụ thể, nó bị hỏng. Đơn giản như vậy (ví dụ: x64 Windows cố gắng ngẫu nhiên hóa các địa chỉ mà tại đó các DLL khác nhau được tải dưới dạng biện pháp bảo mật). –

Trả lời

5

Bạn sẽ phải tắt tính năng Ngẫu nhiên bố cục không gian địa chỉ để tải tệp DLL ở nơi bạn muốn. Một tính năng được thiết kế để ngăn bạn khỏi những gì bạn đang cố gắng làm./Tùy chọn trình liên kết DYNAMICBASE. Tải tại 0x400000 đã hoạt động khi tôi thử nó.

+0

cảnh báo lol LNK4044: tùy chọn không được công nhận "DYNAMICBASE: NO"; bỏ qua, tôi đoán trình biên dịch của tôi đã lỗi thời – SSpoke

2

Không bao giờ dựa vào tải DLL tại một cơ sở cụ thể. Nếu bạn có thể buộc các DLL tải tại một cơ sở cụ thể thì bạn đang mở một lỗ hổng bảo mật tiềm năng.

Nếu bạn có tệp bản đồ, bạn biết bù đắp của một hàm đã cho. Vì vậy, bạn có thể sử dụng GetProcAddress để tìm ra địa chỉ cơ sở của DLL là gì. Đây là một cách an toàn hơn để làm việc ngay cả khi nó có nghĩa là cập nhật DLL của bạn phá vỡ mã tải DLL.

+0

Mã lắp ráp sử dụng toán học để tạo ra lần gọi bù tiếp theo được mã hóa cứng vào địa chỉ cơ sở cụ thể đó. Tôi biết thật là kỳ lạ khi thấy điều này nhưng nó không bao giờ được gọi là chức năng dll ở nơi đầu tiên – SSpoke

+0

@SSpoke: Vâng, nếu bạn không thể tìm ra địa chỉ cơ bản bằng cách sử dụng một mẹo như tôi đề xuất ở trên thì bạn có không có lựa chọn nào khác ngoài việc sử dụng giải pháp của Hans Passant. Chỉ cần nhớ rằng không có gì đảm bảo rằng một phiên bản sau của cửa sổ sẽ không phá vỡ mã của bạn mặc dù. Một giải pháp khác chắc chắn là cách tốt nhất để chuyển tiếp. Tôi không chắc chắn chính xác những gì bạn đang cố gắng làm, mặc dù, nó âm thanh với tôi như bạn có thể sử dụng bất kỳ địa chỉ cơ sở mà bạn chọn. – Goz

+0

Tôi muốn điều đó quá, nhưng tôi đảo ngược kỹ thuật một chương trình lớn với 128 chức năng, giải pháp tốt nhất sẽ là chuyển đổi tất cả các assembly thành mã C hoặc atleast inline nó, nhưng tôi muốn một cách lười biếng cho bây giờ, vì vậy tôi chuyển đổi exe để một dll loại bỏ nó chính() và thay thế nó bằng một dllmain để nó có thể thành công tải như dll bây giờ – SSpoke

Các vấn đề liên quan