Undocument Windows API và VBA

Liên hệ QC

ThangCuAnh

Mới rờ Ét xeo
Tham gia
1/12/17
Bài viết
896
Được thích
792
Giới tính
Nam
Nghề nghiệp
Coder nghỉ hưu, RCE dạo
Cái laptop hư lâu lắc, phải gởi vào thành hồ chứa mưa sữa, mới lấy về.
Nên quay lại tiếp với cái gọi là "rờ chxx em" Windows và VBA.
Topic này tui sẽ đăng lần lượt những gì cu anh tui phát hiện ra trong quá trình "rờ em" Windows API, DLLs và VBAxxx.dll. Các tips, tricks này sẽ bảo đảm không có trên ông "Gấu gồ". Và dùng được cho VBA trên Offices. Chứ "ưn đồ cú mèn" API mà chỉ dùng được cho C/C++, Delphi... thì dân tin học VP ở đây thua.
Tui chỉ sẽ tập trung ở các Windows DLL sau: kernel32.dll, shell32.dll, shlwapi.dll, oleaut32.dll, ole32.dll, advapi32.dll... và 1 ít từ ntdll.dll (core usermode API của Windows). Trên VBExxx.dll thì tui chỉ tập trung vào VBE6 của Office 2007, VBE7 của Office2010 32 và 64bit, các VBExxx.dll khác cũng sẽ gần như tương đượng, không khác nhau mấy.
 
Lần chỉnh sửa cuối:
Mã:
------- v duoc set = obj -------------------
025AECE0: 09 00 00 00 00 00 00 00 58 4C B1 07 00 00 00 00
VarType:
09 00
Reserved1-3:
00 00 00 00 00 00
Data:
58 4C B1 07 00 00 00 00
07B14C6C: 02 00 00 00
07B14C70: 02 00 00 00
Sau khi ta gán v = obj, biến v có địa chỉ trong stack là 025AECE0, dưới biến obj 025AECF0 đúng 10 hex, tức 16 byte, chính là size của 1 biến variant trong Win32 (24 trên Win64). Và các bạn để ý nhé, do trong hàm nó khai báo dưới biến obj, nên địa chỉ của nó cũng thấp hơn biến obj. Đó là quy ước của stack của máy tính, phát triển từ cao xuống thấp.
Dump nội dung trong ruột nó ra, ta thấy field vtType của nó = 09 00, tức là 09 = vtDispatch, 3 word Reserved1 tới 3 là 00, và tiếp đó là địa chỉ chiếm 4 byte của object obj. Tức ObjPtr(obj) = 58 4C B1 07 = 07B14C58 (dư ra 4 byte đằng sau dành cho kiểu 8 byte như Currency, Double...)
Và ta thấy tại 07B14C6C, reference count đã tăng lên 2, VBA đã gọi QueryInterface cho ta.
Nên lúc trước mình đã nói với bé @thuyyeu99 xem cho kỹ, khi 1 biến variant được xem là Is Nothing khi nó có field vtType = 9 và 4 con số ở chổ Data là 00 00 00 00 tức 0 (= nil, = NULL, = nullptr). Win64 thì 8 số nhé các bạn.
 
Lần chỉnh sửa cuối:
Upvote 0
Mã:
------- obj duoc set = nothing tro lai -----
025AECF0: 00 00 00 00
07B14C6C: 01 00 00 00
07B14C70: 02 00 00 00
Khi set obj = nothing, vùng nhớ dành cho biến obj được VBA set = 0 (00 00 00 00)
Nhưng object instance của Dictionary vẫn còn sống, và các bạn thấy reference count của nó xuống còn 1 (01 00 00 00) và Count vẫn = 2 (02 00 00 00). VBA đã gọi Release cho ta. Release giảm reference count xuống 1 mỗi lần nó được gọi. AddRef và QueryInterface thì tăng 1.
Nhưng do nó chưa xuống tới 0 nên nó chưa chết, chưa được free.
Bài đã được tự động gộp:

Mã:
------- v = Empty, Erase obj dict ----------
025AECE0: 00 00 00 00 00 00 00 00 70 B3 77 0B 00 00 00 00
VarType:
00 00
Reserved1-3:
00 00 00 00 00 00
Data:
70 B3 77 0B 00 00 00 00
07B14C6C: 00 00 00 00
07B14C70: 00 00 00 00
Khi ta gán v = Empty, VBA gọi hàm API VariantClear clear nội dung biến variant. Field VarType được set = 0 = VT_EMPTY và data của nó khi thì 0, khi thì rác. Chớ đụng vào. Trong ruột code VariantClear, nó detect thấy VT_DISPATCH thì nó sẽ gọi method Release của object đó. Release giảm xuống 1 tiếp, thấy ồ, tui về 0 rồi, delete this hay Self.Destroy thôi :) Xong phim cuộc đời em :p
Refence Count của object đã về 0, Count cũng về 0. Nó đã được giải phóng, trả lại vùng nhớ đã cấp cho object instance của biến obj kiểu Dictionary về cho Windows. Ta vẫn đọc được 00 do nó vẫn nằm đó và chưa bị cái gì khác được cấp đè lên.
 
Lần chỉnh sửa cuối:
Upvote 0
Mã:
------- v duoc set = obj -------------------
025AECE0: 09 00 00 00 00 00 00 00 58 4C B1 07 00 00 00 00
VarType:
09 00
Reserved1-3:
00 00 00 00 00 00
Data:
58 4C B1 07 00 00 00 00
07B14C6C: 02 00 00 00
07B14C70: 02 00 00 00
Sau khi ta gán v = obj, biến v có địa chỉ trong stack là 025AECE0, dưới biến obj 025AECF0 đúng 10 hex, tức 16 byte, chính là size của 1 biến variant trong Win32 (24 trên Win64). Và các bạn để ý nhé, do trong hàm nó khai báo dưới obj, nên địa chỉ của nó cũng thấp hơn biến obj. Đó là quy ước của stack của máy tính, phát triển từ cao xuống thấp.
Dump nội dung trong ruột nó ra, ta thấy field vtType của nó = 09 00, tức là 09 = vtDispatch, 3 word Reserved1 tới 3 là 00, và tiếp đó là địa chỉ chiếm 4 byte của object obj. Tức ObjPtr(obj) = 58 4C B1 07 = 07B14C58 (dư ra 4 byte đằng sau dành cho kiểu 8 byte như Currency, Double...)
Và ta thấy tại 07B14C6C, reference count đã tăng lên 2, VBA đã gọi QueryInterface cho ta.
Nên lúc trước mình đã nói với bé @thuyyeu99 xem cho kỹ, khi 1 biến variant được xem là Is Nothing khi nó có field vtType = 9 và 4 con số ở chổ Data là 00 00 00 00 tức 0 (= nil, = NULL, = nullptr). Win64 thì 8 số nhé các bạn.
Ủa Win em la 32 mà
Mã:
VarType:

09 00

Reserved1-3:

00 00 00 00 00 00

Data:

00 00 00 00 00 00 00 00

True
 
Upvote 0
Thì nó đang nothing. Code cũ phải không ? Anh đang nói code mới và kết quả trên máy @kieu manh
 
Upvote 0
@$@^#
Nếu vậy trong Del phi muốn kiểm tra Variant is nothing thì pải kiểm tra tất cả cái này hả anh

Value là Unassigned
Value là Clear
Value là Empty
Value là Null
 
Lần chỉnh sửa cuối:
Upvote 0
vậy chốt lại là ta hiểu được bản chất sâu xa của nó là thế .... thì ta ứng dụng nó vào VBA như thế nào là hiểu quả hay cái chi khác ???!!!
 
Upvote 0
Cái tật lanh chanh
Bài đã được tự động gộp:

Các bạn cứ tiếp tục dùng DumpMem với thí xác loại, kiểu dữ liệu đi, kiểu truyền ByRef, ByVal, biến trong hàm, biến trong module, biến kiểu array, dùng trước khi truyền xuống API, sau khi về từ API.
Đủ mọi công dụng đó, do mình nghĩ ra thôi. Thử đi. Sẽ hiểu rõ hơn. Vd tại sao hàm API xxxxA thì phải ByVal, xxxW thì phải StrPtr, String trả về từ hàm API thì sao, bị gì, ai giải phóng. Truyền ByRef str As String xuống API thì phải code dưới API sao, sao hàm TypeName phải là pointer to Variant....
Bài đã được tự động gộp:

Is Nothing là quy ước của VB/VBA, không liên quan gì đến Delphi.
 
Lần chỉnh sửa cuối:
Upvote 0
OK ... chính xác là thế :p vậy mạnh đề nghị như sau:
1/ Chỉ cho mạnh học cách đọc các cái mã 00 aa bb đó đi ... cơ bản nhất để sau này mạnh có thể nhìn thấy bất cứ mã nào rạng đó là có thể đọc được
VD như cho Mạnh cái cần để mạnh tự câu con cá mà nhậu vậy

2/ nếu ngại chỉ thì bỏ qua .... khúc nào cần test mà nhanh ko làm đơ máy hay kéo mỏi tay thì keo Mạnh ... Mạnh giúp nhiệt tình

3/ Nếu 2 cái trên bỏ nốt thì mạnh chỉ quan tâm cái kết nó sẻ như thế nào trong ứng dụng nó ???!!!
 
Upvote 0
Mình nói bé @thuyyeu99 mà, hì hì, sorry.
Cách đọc mã Hex thì mình đã chỉ ở post trên rồi. Cứ đọc từ phải qua trái
 
Upvote 0
OK ... chính xác là thế :p vậy mạnh đề nghị như sau:
1/ Chỉ cho mạnh học cách đọc các cái mã 00 aa bb đó đi ... cơ bản nhất để sau này mạnh có thể nhìn thấy bất cứ mã nào rạng đó là có thể đọc được
VD như cho Mạnh cái cần để mạnh tự câu con cá mà nhậu vậy

2/ nếu ngại chỉ thì bỏ qua .... khúc nào cần test mà nhanh ko làm đơ máy hay kéo mỏi tay thì keo Mạnh ... Mạnh giúp nhiệt tình

3/ Nếu 2 cái trên bỏ nốt thì mạnh chỉ quan tâm cái kết nó sẻ như thế nào trong ứng dụng nó ???!!!
223398
em hiểu chết liền ah
 
Upvote 0
Trong code xử lý Variant của MS, có nhiều field và kiểu dữ liệu Undocument. Tui không hiểu, chỉ lờ mờ thấy lạ. Vd bên Delphi chúng ta vtTypeMask = 0xFFF dùng để And, nhưng coder MS luôn dùng 0xBFFF để And, trong khi VT_ARRAY và VT_BYREF chỉ 0x2000 và 0x4000, còn thiếu đâu 0x5000 ???
Mã:
FFFFFFFF VT_VECTOR  = 1000h
FFFFFFFF VT_ARRAY  = 2000h
FFFFFFFF VT_BYREF  = 4000h
FFFFFFFF VT_RESERVED  = 8000h
FFFFFFFF VT_ILLEGAL  = 0FFFFh
 
Lần chỉnh sửa cuối:
Upvote 0
Trong code xử lý Variant của MS, có nhiều field và kiểu dữ liệu Undocument. Tui không hiểu, chỉ lờ mờ thấy lạ. Vd bên Delphi chúng ta vtTypeMask = 0xFFF dùng để And, nhưng coder MS luôn dùng 0xBFFF để And, trong khi VT_ARRAY và VT_BYREF chỉ 0x2000 và 0x4000, còn thiếu đâu 0x5000 ???
Mã:
FFFFFFFF VT_VECTOR  = 1000h
FFFFFFFF VT_ARRAY  = 2000h
FFFFFFFF VT_BYREF  = 4000h
FFFFFFFF VT_RESERVED  = 8000h
FFFFFFFF VT_ILLEGAL  = 0FFFFh

Lạ vậy à anh??
 
Upvote 0
Tool này coi lặt vặt không anh, chứ không phải tool chuyên nghiệp đâu anh
 
Upvote 0
Tool này coi lặt vặt không anh, chứ không phải tool chuyên nghiệp đâu anh
Thì CŨNG COI được mấy cái Hàm API nó Exports ra ngoài mà xài khi cần thiết là cũng tạm ok rồi
Nhưng khó ăn là làm sao biết được tham số của hàm và hàm đó xài cho việc gì .... lại mò ?!
 
Upvote 0
Thì CŨNG COI được mấy cái Hàm API nó Exports ra ngoài mà xài khi cần thiết là cũng tạm ok rồi
Nhưng khó ăn là làm sao biết được tham số của hàm và hàm đó xài cho việc gì .... lại mò ?!
Hihih nếu dễ vậy thì nói gì nữa, làm gì thì anh cũng phải có kiến thức về mã máy chứ
 
Upvote 0
223713
Làm sao dịch được cái này hả anh?
 
Upvote 0
Mạnh rảnh cũng đang lọ mọ tò mò ... chắc tới tết công gô ròi cũng sẻ biết à :p ===\. ... Nếu có sư phụ thớt này chỉ cho may ra biết còn ko thì chưa biết khi nào ... nhưng rảnh lại mở ra ngó 1 tẹo ( Có file trên GPE mạnh tải code về mà 3 năm sau mới à lên một cái mà .... chơi mà học lo chi thời gian )
mà nó có mối liên hệ gì với Python ta ???? cái khoanh tròn tròn !!!
IDA.JPG
 
Upvote 0
Cái IDA của anh hình như là cái chương trình mà "Rờ Em" hay dùng đó, hình như nó viết bằng Python thì phải
 
Upvote 0
Web KT
Back
Top Bottom