Có thể dùng vba để xóa vba đc không?
Em chào các anh chị!
Có code nào có thể test 1 điều kiện nào đó để xóa toàn bộ vba trong file Excel được không ạ?
Cụ thể là
ô A1! của sheet 1! em đặt điều kiện hoặc =0 hoặc =1.
Khi Open file:
ô a1=1 thì file chạy bình thường.
Nếu A1=0 thì toàn bộ vba trong file bị xóa sạch.
Có được không ạ?
Thế thì cho bạn cái "cần câu"
Sub Test()
With ThisWorkbook.VBProject
.VBComponents.Remove .VBComponents("Module1")
End With
End Sub
"câu cá" thế nào là tùy bạn nhé
FileFormat:=51 <==> FileFormat:=xlOpenXMLWorkbook—> Cũng là thằng em XLSX
Bạn cứ vào cửa sổ VBE, gõ đâu đó cái này ThisWorkbook.SaveAs, bôi đen nội dung vừa gõ rồi nhấn F1, tại hàng mô tả về FileFormat, bạn sẽ nhìn thấy một danh mục XlFileFormat. Click vào đó là bạn có thể biết tất cả về mấy con số này thôi mà.
Còn câu lệnh xóa file thì chỉ là như vầy thôi mà: Kill "Đường dẫnTên file"
Tóm lại là bạn cần làm 2 việc:
1. SaveAs file gốc thành file .xlsx (file mới sẽ không còn code nữa).
2. Xóa file gốc đi bằng lệnh Kill.À đấy! phải thế chứ! thiếu việc 2! =))
Cần gì phải đau khổ đến thế chứ, muốn xây thì khó chứ đập ra thì nhanh lắm
Sub Xoa_Modules()
Dim x
On Error Resume Next
With ActiveWorkbook.VBProject
For x = .VBComponents.Count To 1 Step -1
.VBComponents.Remove .VBComponents(x)
Next x
End With
End Sub
Còn việc Saveas thì có thể dùng thêm dòng lệnh Application.displayalerts=False để lưu đè lên file gốc rồi mà, đâu cần phải xoá nữa
Nếu bạn biết viết code rồi thì cái này đơn giản mà
Vấn đề là với mỗi loại file nó có phần mở rộng khác nhau mà anh. Chẳng hạn, file gốc là Test.xlsm, sau khi SaveAs thì nó thành Test.xlsx chứ nhỉ?!
Theo hướng làm ở trên thì em làm như vầy:
Sub Test()
Application.DisplayAlerts = False
ThisWorkbook.SaveAs "C:Test.xlsx", 51
Application.DisplayAlerts = True
Kill "C:Test.xlsm"
End Sub
Ồ! Ngon. :D.
Mà… Bác nói vậy chứ code em cũng biết viết gì đâu. Chỉ là biết mỗi cái copy và pase thêm 1 tý mô đi phê nữa… hehe!
Tks Bác!Bạn có chắc chắn là "ngon" 100% không?
Tôi hiểu "xóa toàn bộ vba" của bạn là xóa toàn bộ code trong VBA. Tôi hiểu đúng?
Bạn nên hiểu là xóa component và xóa code là 2 "cô nàng" khác nhau. Code của quanghai là xóa component.
Trong VBE ở bên nửa trái bạn có component, bên nửa phải bạn có code. Nếu component bị xóa thì dĩ nhiên code của nó cũng "cuốn theo chiều gió". Thế nếu component không bị xóa thì sao? Theo lôgíc thì code vẫn còn trơ trẽn nằm tơ hơ.
Code của quanghai không xóa Sheet1, 2, 3, ThisWorkbook, vậy nếu chúng có hằng hà sa số code thì những code này vẫn còn.
Vậy nếu bạn muốn xóa class module, module, userform, …, code của Sheet1, 2, 3, …, ThisWorkbook thìSub DeleteAllCodes() Dim x On Error Resume Next With ActiveWorkbook.VBProject For x = .VBComponents.Count To 1 Step -1 If .VBComponents(x).Type <> 100 Then .VBComponents.Remove .VBComponents(x) Else With .VBComponents(x).CodeModule .DeleteLines 1, .CountOfLines End With End If Next x End With End SubCode cũng hơi độc hại nên em tính cất lại chút ít. Em viết thế này
Sub Xoa_Code()
Dim x As Integer
On Error Resume Next
With ActiveWorkbook.VBProject
For x = .VBComponents.Count To 1 Step -1
.VBComponents(x).CodeModule.DeleteLines 1, _
.VBComponents(x).CodeModule.CountOfLines
.VBComponents.Remove .VBComponents(x)
Next x
End With
End SubĐúng rồi! Cám ơn Bác nhé!
Em cũng đang thắc mắc vấn đề này từ lúc code của Thầy Ndu cơ.
Thật ra đến thời điểm này Em cũng chưa test 1 trường hợp nào trong bài này cả.
Nên có post nên sợ các Bác bảo lười.
VBA thì có rất nhiều trong sheet như Bác nói, This wordbook nữa.
module,UserForm,class v.v…
Tóm lại là xóa sạch…
Cái này E sẽ thử nó!Theo tôi nghĩ, code dạng này, theo tác giả là không cho xem code nên mới xóa, thì OK, nhưng nếu người ta không để chế độ tự động chạy macro (macro setting) thì cũng chẳng có gì xảy ra.
Mặt khác, nếu ta giấu code, đặt password cho VBA cũng không là vấn đề. Nếu người muốn thấy code của mình, tức là người đó cũng hiểu biết và thậm chí hiểu biết rất rõ về VBA thì không xóa được với họ đâu, họ không cho chạy macro, rồi họ bẻ khóa (diễn đàn nói nhiều về việc này), thì code cũng sẽ lộ ra ngay trước khi code xóa VBA thực hiện!
Nên tôi nghĩ hướng dẫn thì ta cứ hướng dẫn, chẳng ngại ngùng gì! Người không biết chẳng ai thèm quan tâm đến code, người quá hiểu biết thì có xóa, giấu, cũng không được, chỉ có giấu người dỡ dỡ ương ương thôi.
www.giaiphapexcel.com/diendan/threads/c%C3%B3-th%E1%BB%83-d%C3%B9ng-vba-%C4%91%E1%BB%83-x%C3%B3a-vba-%C4%91c-kh%C3%B4ng.72632
Thiết kế Tổng đãi ngộ (Total Rewards) theo khung SHRM
Khóa học “Thiết kế Tổng phần thưởng (Total Reward) chuẩn khung SHRM” giúp bạn nắm vững toàn bộ hệ thống đãi ngộ theo chuẩn...
Xem khóa học
Mở khóa trong vòng 3s
Em cũng dùng Hexeditor nhưng làm quen tay rồi anh à:
– Ctrl + F
– Gõ CMG, Enter
– Bôi đen chổ cần xóa rồi bấm nút Delete và Save
Xong!
Ẹc… Ẹc… 3s hơi cường điệu nhưng sự thật là rất nhanh
Vấn đề Unprotect Password VBA tôi đã nghiên cứu từ rất lâu rồi mà dường như.. không có cách
Tham khảo các trang web nước ngoài, người ta cũng chỉ có thể dùng phương pháp SendKeys (kiểu như "dạy" cho máy tính cách ta làm bằng tay bằng cách bấm các tổ hợp phím nào đó)
Tuy nhiên, phương pháp dùng SendKeys đôi lúc không ổn định, khi được khi không nên tôi chưa giới thiệu
Nghe đồn rằng có cách dùng hàm API để truy đến các cửa sổ lập trình VBA gì gì đó nhưng tiếc là tôi lại không rành —> E rằng làm được món này chỉ có thể là siwtom —> Chở xem
——————————————
Lại bị gọi lên bảng.
ndu nói thế là không đúng. Tự tôi không nghĩ ra được code vì cái khoản này nó thuộc "lập trình cao
cấp". Nhưng khi lập trình trong Delphi thì tôi cũng gặp và hiểu được cơ cấu của nó là như thế nào.
Và khi tôi đọc qua code có trong Excel.xls của quanghai gửi thì 99,99% tôi chắc chắn là nó sử dụng
"kỹ thuật lập trình cao cấp" mà tôi sẽ giải thích dưới đây.
Nếu các bạn có chút thời gian thì tôi sẽ giải thích nôm na nó như thế nào. Nôm na vì tôi sẽ dùng
ngôn ngữ thường ngày để giải thích chứ dùng ngôn ngữ "chuyên ngành" thì e rằng người không lập
trình khó hiểu.
—————
1. Trước tiên nói về cái cửa sổ mà Excel bắt ta phải nhập mật khẩu. Như trong code Excel.xls "đã
chỉ rõ" thì Excel gọi hàm system là DialogBoxParam để hiển thị cửa sổ hộp thoại. Tất nhiên Excel
phải tạo một cửa sổ hộp thoại (template) đặt trong resource và truyền thông tin về nó cho hàm
DialogBoxParam. Hàm DialogBoxParam sẽ tạo (trên cơ sở template) hộp thoại và hiển thị. Excel
cũng phải lập một procedure cho cửa sổ (DialogProc) mà DialogBoxParam tạo và hiển thị. Để làm
gì? Để nhận các thông điệp. Vd. Windows sẽ gửi thông điệp WM_INITDIALOG khi cửa sổ được
khởi tạo. Ta có thể khi nhận được thông điệp này (tức ở thời điểm "chào buổi sáng") làm một số
việc thiết lập ban đầu, tạo thêm controls – nó giống như ta thiết lập một số cái trong
UserForm_Initialize ấy mà. Windows cũng gửi thông điệp khi user nhấn nút nào đấy (chỉ rõ là nút
nào) để DialogProc xử lý. Vd. nếu nút nhấn là Cancel thì code DialogProc "dọn đồ ra về" còn nếu là
OK thì kiểm tra dữ liệu nhập rồi cũng "dọn đồ" – tức hủy hộp thoại. Tất nhiên Windows còn gửi nhiều
thông điệp khác, nếu DialogProc "quan tâm" thì xử lý.
Khi người lập trình muốn hủy hộp thoại (user chọn Cancel?, chọn OK? …) thì code của DialogProc
phải gọi EndDialog để system biết và hủy hộp thoại. Khi gọi EndDialog thì phải truyền kết quả trả
về dưới dạng thông số của EndDialog. Hàm DialogBoxParam cũng sẽ trả vể kết quả này. Từ cơ
cấu như trên thì người lập trình có thể viết code đại loại như sau:
a – Gọi hàm DialogBoxParam để tạo cửa sổ nhập mật khẩu – template sẽ gồm textbox (class "Edit"
của Windows) để nhập mật khẩu, nút OK và Cancel. Trong DialogProc nếu nhận được thông điệp
do Windows gửi nói là user nhấn Cancel thì gọi EndDialog(hDialog, 0) – hDialog là "handle to
dialog box", 0 là giá trị trả về, cũng là giá trị mà hàm DialogBoxParam trả về. Nếu thông điệp nói là
user nhấn OK thì: kiểm tra mật khẩu có đúng không, nếu đúng thì EndDialod(hDialog, 1) còn nếu sai
thì EndDialog(hDialog, 0)
Cũng cần nói rõ là khi gọi hàm DialogBoxParam và cửa sổ hiển thị thì hàm DialogBoxParam chỉ
trở về, và mọi code sau dòng gọi hàm DialogBoxParam được thực hiện, khi mà hộp thoại được
đóng (do code trong DialogProc gọi EndDialog). Trong suốt thời gian hộp thoại hiển thị thì chỉ có
code trong DialogProc được thực hiện mà thôi (kiểu như ShowModal ấy mà – cho tới khi cửa sổ
được đóng thì mọi code sau ShowModal "phải chờ")
b – Ở dòng code sau dòng gọi hàm DialogBoxParam thì người lập trình kiểm tra giá trị trả về bởi
hàm DialogBoxParam. Nếu là 0 (tức user chọn Cancel hoặc chọn OK nhưng mật khẩu sai) thì:
Còn nếu là 1 (user chọn OK và nhập đúng mật khẩu) thì mở code cho user xem.
—————–
Như trên đã thấy thì bình thường người lập trình sẽ làm trình tự như trên và Excel cũng làm như thế.
Bây giờ ta hình dung là ta viết code như sau:
Ta viết hàm DialogBoxParam "nhái" – vd. hàm MyDialogBoxParam, và đánh tráo nó với hàm
DialogBoxParam của system. Tất nhiên hàm "nhái" này phải có cấu trúc thông số y hệt hàm của
system. Lúc này nếu có "ai đó" gọi hàm DialogBoxParam thì Windows sẽ gọi hàm
MyDialogBoxParam. Hàm của ta nếu kiểm tra thấy template = 4070 thì chả hiển thị hộp thoại nào
cả mà hàm trả về luôn giá trị 1. Trong trường hợp ngược lại thì tráo lại thành hàm DialogBoxParam
của system và gọi nó – vì trong cùng thời điểm có thể những phần mềm khác trong system cũng gọi
hàm DialogBoxParam, ta phải trả lại "hiện trạng" cũ để các phần mềm đó hiển thị hộp thoại của
mình. Cách làm thế nào?
—————
Tất cả các hàm của system đều nằm trong các thư viện động DLL. Mỗi thư viện như thế có nhiều
section, có header. Riêng về các function trong thư viện thì: Khi DLL được load vào RAM thì nó
nằm ở một chỗ nào đó, địa chỉ nào đó trong RAM. Lúc này mỗi function cũng nằm ở một địa chỉ
nào đó trong RAM. DLL là "dùng chung" cho mọi process, tức nếu A, B, C cùng "gọi" bla.dll thì
bla.dll sẽ được ánh xạ vào mỗi "không gian địa chỉ" của mỗi process A, B, C. "Địa chỉ" của mỗi
function có trong DLL sẽ được ghi trong RAM ở "đâu đó" trong phần header, mỗi function có 1
trường để ghi địa chỉ của nó. Ta xét vd. hàm DialogBoxParam. Giả sử "ở đấy ở đấy" có giá trị là
"123456789" thì bình thường khi process gọi hàm DialogBoxParam thì system sẽ tới "chỗ ấy chỗ
ấy" để đọc ra địa chỉ của hàm DialogBoxParam – sẽ đọc được "123456789". Lúc này sẽ có 1
bước nhẩy tới địa chỉ "123456789" và thực hiện code của DialogBoxParam vì code của
DialogBoxParam nằm ở địa chỉ ấy mà.
Bây giờ ta hãy tưởng tượng là ta viết hàm MyDialogBoxParam (hàm nhái) mà nó nằm ở địa chỉ
"abc…xyz" (đọc ra bằng AddressOf). Code sau đó nhẩy tới "chỗ ấy chỗ ấy" và ghi giá trị "abc…xyz"
đè lên "123456789". Từ lúc này mỗi khi process nào đó gọi DialogBoxParam thì system nhẩy tới
"chỗ ấy chỗ ấy" và đọc ra địa chỉ "abc…xyz" (chứ không phải "123456789" nữa) và nhẩy tới địa chỉ
"abc…xyz" để thực hiện code. Chỉ có điều ở "abc…xyz" là code của hàm nhái MyDialogBoxParam
chứ không phải của hàm DialogBoxParam.
Tất nhiên trước khi đánh tráo địa chỉ của hàm được ghi ở "đâu đó" (trong header của DLL) trong
RAM thì ta phải ghi nhớ nó để sau đó trả về hiện trạng cũ – lại tới "chỗ ấy chỗ ấy" và ghi vào
"123456789" đè lên "abc…xyz"
Những kỹ thuật: xin phép thao tác trong RAM ở vùng nào đó, ghi trong RAM, đánh tráo địa chỉ hàm
… là những kỹ thuật cao cấp. Người có trình độ trung bình cũng có thể thao tác trong RAM nhưng để
đánh tráo địa chỉ thì phải thông hiểu nhiều hơn mới biết cách làm – thay đổi những bai nào trong
RAM, ở đâu …
—————-
Trở lại code của quanghai gửi nếu tôi không lầm thì hiện thời code "chưa làm gì cả". Vì khi hiển thị
FrmHookMain và nhấn nút "RemoveVBAPassword" thì code đánh tráo địa chỉ của hàm
DialogBoxParam (thay vì hướng tới DialogBoxParam thì hướng tới hàm nhái MyDialogBoxParam)
nhưng ta không click được vào VBAProject để xem code. Phải đóng FrmHookMain mới click vào
được. Nhưng khi đóng FrmHookMain thì địa chỉ cũ lại được trả lại (đánh tráo lại) trong
UserForm_Terminate nên lúc này có nhấn VBAProject thì hàm DialogBoxParam lại được thực hiện
chứ không phải hàm nhái nên ta lại thấy hộp thoại bắt nhập mật khẩu hiện ra.
Vậy trong tập tin đính kèm tôi làm như sau:
a – Trên Sheet có 2 nút: "Đánh tráo" và "Trả lại"
b – Trước tiên ta nhấn "Đánh tráo", code của nó là:
Từ lúc này mọi cuộc gọi hàm DialogBoxParam thì thực chất là gọi hàm nhái MyDialogBoxParam
mà nó sẽ trả về 1, tức Excel sau đó kiểm tra thấy 1 được trả về thì tưởng rằng user nhập đúng mật
khẩu và nhấn OK – y như cái procedure của hộp thoại mà nó thiết kế trả về khi user nhập đúng mật
khẩu và nhấn OK.
c – Ta nhấn VBAProject để xem và copy code
d – Ta nhấn "Trả lại" để thực hiện code RecoverBytes. Nó sẽ trả lại (trong RAM) địa chỉ cũ của hàm
DialogBoxParam.
—————–
Nói đến test thì tôi lại là vua lười.
Vậy ndu hãy test và thông báo kết quả thế nào
Cái này để mình bàn trong 1 dịp khác nha anh (vi phạm nội quy đấy)
Không phải, hiểu lầm nhau rồi.
Code là của tác giả tập tin mà quanghai gửi lên. Tất nhiên tôi cũng từng viết trong Delphi để đánh tráo hàm nhưng cái code này đã có sẵn nên chả cần viết gì cả.
Chỉ có điều tôi biết về "kỹ thuật đánh tráo" nên chỉ đọc lướt qua code của tập tin do quanghai gửi lên thì tôi nhận ra ngay là nó đã làm thế nào. Do hiểu được nên tôi sửa chút để không hiển thị Form nào cả mà "đánh tráo" lúc nào" và "Trả về" thế nào. Chỉ thế thôi.
Mà code không Remove password. Nói ngắn gọn thì thế này:
Excel gọi hàm của system để hiển thị hộp thoại. Nếu user nhập đúng password và nhấn OK thì hàm trả về 1. Nếu nhấn Cancel hoặc nhập sai password thì trả về 0. Khi hộp thoại đóng thì Excel kiểm tra kết quả trả về của hàm vừa gọi. Nếu là 1 thì nó "cho là" user nhập đúng password và nhấn OK. Vậy nó mở cho user xem code. Không phải xóa password vì lần sau mở ra thì lại phải đánh tráo mới xem được.
Bây giờ ta đánh tráo sang là gọi hàm "nhái" của ta. Hàm nhái chả hiển thị cóc khô gì mà về luôn cùng với giá trị 1. Và Excel kiểm tra giá trị trả về thì thấy là 1 nên "tưởng" là user nhập đúng password và nhấn OK
Công to là của quanghai sưu tầm.
Nếu sốc thật thì cũng dể hiểu thôi. Không phải vô cớ mà chuyện đánh tráo hàm này là một trong những món "đặc sản" của hacker và rootkit. Họ là những người rất am tường về system, hiểu cơ cấu và cách thức hoạt động của system nên họ có thể đột nhập vào system để làm mưa làm gió.
Ngay như đột nhập vào một căn nhà có hệ thống cảnh báo chẳng hạn. Người thường thì không biết cách nhưng người am tường thì biết vào đường nào. Cửa chính, phụ? Qua đường hệ thống thông gió? Chỗ nào là điểm yếu của căn nhà? Vào rồi thì do am tường về các hệ thống cảnh báo nên họ biết phải "tắt" cái gì, tắt ở đâu v…v
Còn về "thuật toán" thì đơn giản thôi.
Giả dụ ta có ông A (system Windows) trực. Khi khách hàng gọi điện tới đặt ông sửa ống nước chẳng hạn (process gọi hàm Windows – SuaOngNuoc) thì ông A "đi" tới bảng ghi số điện thoại và đọc số của ông sửa ống nước (mỗi ngày có 1 ông khác với số khác – tương đương với mỗi lần DLL được load vào RAM thì nó nằm ở một địa chỉ khác), sau đó gọi cho ông thợ (nhẩy tới địa chỉ của hàm) và "kích hoạt", "cử" ông thợ đi làm (thực hiện code ở địa chỉ vừa nhẩy tới).
Thế bây giờ nếu ta "lén" sửa lại số điện thoại được ghi trên bảng và thay vào đó ghi số của nhân viên của ta thì sao? Thì ông A sẽ gọi cho nhân viên của ta và "cử" nhân viên củ ta đi làm, thế thôi.
Hàm Hook này là dạng boolean luôn trả về TRUE khi hoàn tất thủ tục, mở đầu Hook = False và kết thúc hàm là Hook = True
Theo em nghĩ, Khi ta dùng IF HOOK THEN tức là ta đã "gián tiếp" gọi hàm đó, dĩ nhiên nó phải kiểm tra HOOK và từ đó HOOK chạy từ False rồi thực hiện thủ tục, sau cùng trả về TRUE.
Tầm trình độ của chúng ta thường hay viết khác:
– Viết code cho Sub Hook (chứ không phải Function)
– Dùng 1 biến public chk kiểu Boolean để kiểm tra xem Sub Hook đã chạy hoàn tất chưa
– Xong, viết 1 Sub khác cho gọi sub Hook, đồng thơi kiểm tra biến chk, nếu chk=TRUE thì sẽ làm việc khác
Tuy nhiên, các nhà lập trình chuyên nghiệp thường hay viết kiểu khác: Thay đổi Sub Hook thành Function Hook và Function này trả về giá trị kiểu Boolean luôn.
Vậy nếu code trong Hook hoàn tất thì hàm trả về kết quả = TRUE và ngược lại
Cách này có cái tiện là khỏi cần phải qua biến tạm dạng Public
——————-
Anh viết vậy không đúng —> Biến Hook của anh hóa ra trùng với tên hàm à
Lý ra chỉ vầy là được
Vẫn chỉ là cách viết thay vì If Hook = True Then người ta viết If Hook Then cho nó khỏe (nghe nói code chạy nhanh hơn)
Thì cũng giống vầy thôi
Em không nghĩ là anh lại thắc mắc chuyện đơn giản này
Ẹc… Ẹc…
Anh viết vậy là… quá thừa rồi còn gì
SheetExist là 1 Function chứ đâu phải 1 Sub —> Nếu nó chạy thì nó phải trả về giá trị gì đó và ta phải "nhận" lấy để tính toán xem sẽ làm gì tiếp
Còn cách anh vừa viết là anh đã tự xem SheetExist là 1 Sub (không phải Function) và giá trị trả về của nó anh cũng không thèm đếm xỉa đến luôn….
Dòng đỏ ở trên chẳng biết để làm cái gì nữa, có chăng thì vầy mới hợp lý:
Nói cho cùng thì cũng y chang cách em đã viết ở bài 57 thôi
Ẹc… Ẹc… (ngộ hen.. tự nhiên anh lại théc méc rất.. kỳ cục…)
Bạn có 3 cách viết:
1.
a = Hook
if a then
2. if Hook = TRUE then
3. if Hook then
————
Bạn biết gì về cấu trúc: IF đk THEN?
đk là biểu thức trả về giá trị lôgíc – boolean.
Khi gặp cấu trúc IF đk … thì trước tiên biểu thức đk được tính giá trị, sau đó tùy giá trị thế nào mà thực hiện code.
Ta có các biến lôgíc, các hàm trả về giá trị lôgíc … Chúng được kết nối với nhau bởi OR, AND, và >, <, >=, <=, = (với 2 vế không nhất thiết là các giá trị lôgíc).
Với a, b, HamGiDo(…) as boolean, c, d as Long thì:
TRUE, FALSE, a, b, HamGiDo, (a or b), (a or b) and HamGiDo, c = d, (c = d) and b, c >=<= d v…v đều là biểu thức.
Có thể nói TRUE, FALSE, a, b, HamGiDo là những biểu thức đơn.
Với IF HamGiDo THEN thì cũng như mọi khi thôi, tức trước tiên cần tính giá trị của "biểu thức" HamGiDo. Việc tính giá trị của biểu thức HamGiDo là việc xác định giá trị trả về bởi HàmGiDo, tức code của HamGiDo phải được thực hiện và giá trị trả về sau khi thực hiện code là giá trị của biểu thức.
Hàm Hook sau khi thực thi thì trả về giá trị Boolean cũng chính là giá trị của biểu thức điều kiện, thế thôi.
Khi bạn tính biểu thức trong đó có sin(x) (Riêng sin(x) cũng là biểu thức rồi) thì bạn "bấm" máy tính tay (tức thực hiện code tính sin): x –> sin, còn khi máy nó gặp HamGiDo thì nó "thực hiện code" của HamGiDo và có kết quả do hàm trả về.
Kiểu viết 2 và 3 như trên kết quả là như nhau nhưng thực hiện có sự khác nhau đấy nhé.
Ta tính giá trị của biểu thức (a = b), a và b có thể có dạng tổng quát vd. a = x + y, b = k + l + m + n
Việc tính được giá trị của a hay b vẫn chưa xong. Giá trị của biểu thức (a = b) được tính như sau:
1. tính a
2. tính b
3. tính a = b (so sánh)
Với a, b as boolean tương tự. Tính được a hay b TRUE hay FALSE vẫn chưa kết luận được gì về giá trị của biểu thức a = b. a có thể = FALSE, b = FALSE nhưng a = b = TRUE.
Với IF Hook then thì có được giá trị trả về của Hook cũng chính là giá trị của đk thì việc xác định đk kết thúc.
Với IF Hook = TRUE then thì dù có được giá trị do Hook trả về thì giá trị của đk vẫn chưa được xác định. Phải thực hiện phép so sánh Hook = TRUE mới có được giá trị của đk.
————
Cũng nên nhớ là nếu bạn có hàm Hichic và bạn viết: call Hichic (Hichic) thì có nghĩa là: code của Hichic được thực hiện nhưng kết quả trả về không dùng làm gì cả, không được lưu ở đâu cả.
Nhưng khi bạn có:
a = Hichic
b = 5 + Hichic
IF Hichic > a + sin(xyz) THEN
….
Thì không chỉ là code của Hichic được thực thi mà giá trị do nó trả về còn dùng cho các tính toán tiếp theo.
Vì vậy với cùng một hàm Hichic thì "chỗ này" bạn cần giá trị do hàm trả về thì bạn viết: a = Hichic, nhưng ở "chỗ khác" bạn không cần giá trị trả về mà chỉ cần thực thi code thôi (hàm không chỉ trả về giá trị mà hàm có thể làm nhiều việc trong code) thì bạn viết: call Hichic. Bạn có thể viết a = Hichic nếu muốn nhưng không bắt buộc.
Tôi đã viết rồi. Bạn đặt mật khẩu thì Excel hiển thị hộp thoại bắt bạn nhập rồi khi đóng hộp thoại thì Excel kiểm tra xem kết quả có "thỏa mãn" nó không, nếu có thì "mở". Do Excel gọi hàm của system để tạo hộp thoại nên mới có cơ hội đánh tráo hàm này bằng hàm của ta, mà hàm của ta chả hiển thị hộp thoại nào cả và trả về kết quả "thỏa mãn" Excel. Thế thôi.
Còn khi mà "người ta" không gọi gì cả để hiển thị hộp thoại nhập mật khẩu ("người ta" có đòi hỏi gì đâu mà hiển thị hộp thoại nhập mật khẩu?) thì tráo cái gì? Mà tráo cái gì, để làm gì? "Người ta" có cần kết quả nào đâu? "Người ta" đá đít mình luôn chứ có yêu cầu gì đâu?
Tôi đã nói rồi. Với dạng file như của quanghai thì bạn thử … đọc ký chủ đề này đi. Bệnh khác thì phải dùng thuốc khác. Trong chủ đề có nói chút về thuốc mà.
À mà "muốn như thế" có nghĩa là gì?
Là muốn bỏ "Project is unviewable"? Nếu thế thì đọc bài của dhn46
Là muốn bắt chước người ta làm "Project is unviewable"?
————
Một khi ta đã biết là nếu cần bỏ "Project is unviewable" thì trong HexEditor ta có thể sửa CMG,
DPB, GC thì để làm được "Project is unviewable" ta cũng "tìm" ở "chỗ đó" thôi.
Tôi đã thử "vài cái" thì thấy làm cũng đơn giản thôi.
Tôi chỉ cách tốn ít thao tác nhất.
Bạn mở HexEditor –> chọn trong HexEditor để mở tập tin Excel mà bạn cần thao tác.
Chọn Search và tìm CMG. Bạn sẽ thấy đại loại là CMG="C4C6276D2F3533353335333533"
Bạn hãy sửa 1 ký tự trong ngoặc " " sang ký tự khác thuộc tập . Bạn có thể sửa tất cả các ký tự nhưng ta đã
thống nhất với nhau là ít thao tác nhất rồi mà.
Ở lân cận CMG cũng có đại loại DPB="…". Bạn cũng sửa 1 ký tự trong ngoặc. Rồi ở gần có
GC="…". Làm tương tự. Save lại tập tin. Xong
Mang đi "dọa" đồng nghiệp
– Mở file bằng Hexeditor
– Xóa sạch hết từ CMG đến GC
– Lưu file lại
– Mở file lên kiểm tra —> Bất cứ thằng Unview hay Protect VBA gì gì đó cũng sẽ đi.. Pháp ở
Thế bạn trở thành dũng sỹ diệt code rồi, ha ha…
Nói vậy chớ xóa hết từ chữ "CMG" đến hết nội dung của GC, khi nào thành một loạt dấu …….(chấm) là được.
Hình như hôm trước tôi gửi video clip cho bạn rồi mà
KnrSHYUjZhE
Thì làm giống y chang như tôi đã làm thôi (trước giờ chưa từng bị bất kỳ lỗi gì)
Chú ý:
– Ctrl + F
– Đặt con trỏ chuột về phía bên phải số 47 rồi bấm Delete 3 phát
– Xong, đặt chuột vào ô vuông màu xanh, gõ CMG và bấm nút Find
Nói chung cứ chú ý kỹ thao tác tôi làm trong video clip là được rồi
UEea2PXp4eY
Tôi nghĩ là cái EXE kia chỉ là trá hình thôi. Từ đâu nó có "nội dung" file Excel để mà mở bằng Excel?
Vì vậy tôi nghĩ là toàn bộ nội dung file Excel "thằng" EXE kia nó có "trong cơ thể nó". Tức người viết code EXE "đính kèm" file Excel ở dạng resource (chuẩn), hoặc làm kiểu a ma tơ thì khi làm xong EXE thì dùng phần mềm "nối" file Excel vào đuôi EXE.
Khi EXE được kích hoạt thì nó "bung" file Excel từ resource, hoặc cắt từ đuôi EXE (tất nhiên cắt từ đâu thì cái phần mềm kia sẽ ghi, vd. 4 bai ở đuôi EXE sẽ dùng để ghi độ lớn của file Excel –> khi được kích hoạt thì EXE nhẩy tới 4 bai cuối để đọc độ lớn của file Excel, giả dụ là x –> EXE nhẩy tới bai cách bai cuối cùng (offset tính từ cuối) là x + 4 rồi đọc x bai – tóm lại phần mềm kia trước tiện ghi file Excel vào đuôi EXE sau đó ghi tiếp trong 4 bai độ lớn của file EXE, tổng cộng số bai ghi vào đuôi EXE là x + 4. Khi đọc ra thì EXE đọc 4 bai cuối để có x, sau đó nhẩy xuống cuối EXE "thực", tức offset = x + 4 tính từ cuối rồi đọc x bai liên tiếp), ghi lên đĩa
Do việc "nhúng" file Excel vào EXE có thể có nhiều cách (resource, a ma tơ) nên khó nói là lọc file Excel từ EXE như thế nào.
Nếu bạn đã từng dùng phần mềm để "convert" file Excel thành EXE thì hãy gửi lên cho tôi phần mềm đó. Tôi sẽ thử xem nó làm như thế nào. Nếu đúng là nó "nhúng" file Excel vào EXE thì chuyện tách ra không có gì là khó. Chỉ sợ là trước khi nhúng nó mã file Excel thì chịu vì biết nó mã thế nào để mà giải mã?
—————–
Mà nếu đúng là khi được kích hoạt nó sẽ "bung" file Excel từ trong "cơ thể" nó rồi ghi trên đĩa cững để gọi Excel mở thì chỉ cần dò xem nó ghi ở đâu trên đĩa cứng thì lấy thôi. Cái dò này thì ai cũng làm được.
Bạn có file Excel đã được "convert" sang EXE không? Nếu không có gì bí mật thì gửi cho tôi xem.
————–
Tất nhiên có thể mỗi thằng làm một khác, và không nhất thiết như tôi nói. Do có thể mỗi thằng làm một khác nên để biết chúng làm thế nào thì phải xét từng thằng cụ thể.
Vd. nếu bạn dùng thằng này
https://www.drmsoft.com/Excel-to-exe-converter.asp
thì tôi nghĩ việc lấy được file nguồn là hoàn toàn dễ dàng. Ít ra thì tôi cũng đã thử dùng nó để convert 1 file Excel sang EXE rồi khi kích hoạt EXE thì tôi lấy được file nguồn.
Đây là project trên Excel 5.0/95 nên khi mở ra trên Excel 2007 thì có thông báo và VBA bị loại hết.
Của quanghai và Hong.Van đều như vậy.
Mình nói ngoài lề tí nha: Sau khi dùng code của siwtom và unlock toàn bộ các Add-Ins của Microsoft… mọi người đã nhìn thấy code rồi, vậy có "chôm" được gì của bác Bill không (tức là học được gì ấy) hay chỉ là "nhìn" rồi… tối thui, chẳng biết ông Bill viết code quỷ gì cả?
Ẹc… Ẹc…
Code là tổng quát mà.
Bạn định xóa code của một hàm, phương thức nào đó? Rõ ràng nó phải có tên, đúng không? Thì nhập tên đó vào chỗ ProcedureName, tức thay cho "tinh toan" thì nhập vd. "MySecretFunction", với "MySecretFunction" là tên của hàm, phương thức cần xóa. Hơn thế nữa "MySecretFunction" nằm trong một module nào đó, đúng không? Giả dụ nằm trong "MySecretModule" thì thay vì "module2" thì nhập "MySecretModule" vào chỗ DeleteFromModuleName. Tất nhiên cái "MySecretModule" nó có trong workbook nào đó, đúng không? Thì nhập workbook đó vào chỗ wb thay cho Workbooks("vbe.xls"). Tức có thể nhập: Workbooks("MySecretBook.xls"), Workbooks(Book1.xls), Workbooks(1) v…v
Ví dụ là ví dụ về cách gọi. Khi bạn gọi phương thức thì bạn phải truyền thông số cụ thể cho lần gọi ấy chứ.
Đương nhiên được chứ anh
Ví dụ code lấy các Procedures trong 1 Module
Function ListProcedures(ByVal ModuleName As String)
Dim LineNum As Long, NumLines As Long, i As Long, Arr(), ProcName As String
With ActiveWorkbook.VBProject.VBComponents(ModuleName).CodeModule
LineNum = .CountOfDeclarationLines + 1
Do Until LineNum >= .CountOfLines
ProcName = .ProcOfLine(LineNum, 0)
ReDim Preserve Arr(i)
Arr(i) = ProcName: i = i + 1
LineNum = .ProcStartLine(ProcName, 0) + _
.ProcCountLines(ProcName, 0) + 1
Loop
End With
ListProcedures = Arr
End Function
Áp dụng =ListProcedures("Module1") —> Sẽ lấy tên các Procedures trong Module1
Anh xem file dưới đây nhé
Thì anh làm vầy
Ubound(Arr) chính là cái anh cần
——————–
Còn vụ lấy listModule, em nghĩ chắc là vầy:
Function ListModule()
Dim mod_ As VBComponent
Dim n As Long
Dim Arr()
For Each mod_ In ActiveWorkbook.VBProject.VBComponents
If mod_.Type = 1 Then
n = n + 1
ReDim Preserve Arr(1 To n)
Arr(n) = mod_.Name
End If
Next
If n Then ListModule = Arr
End Function
—————–
Oh mà xem lại thì thấy mấy bài cuối chẳng ăn nhậu gì đến vụ DÙNG CODE VBA ĐỂ XÓA VBA cả. Anh TrungChinhs có thấy vậy không?
Ẹc… Ẹc… lộn tiệm dễ bị mod xóa bài quá
Nói chung là phải chỉnh lại Trusted Center mới dùng được code trong topic này
Thì lỗi của bạn thôi. Lần sau đọc cho kỹ nhé.
Mà "xóa dòng" là không chính xác (xóa vài dòng trong SUB, trong MODULE? – làm gì có chuyện đó). Code xóa toàn bộ code của 1 hàm, phương thức có tên cho trước trong module có tên cho trước trong book cho trước.
Tôi thường đọc kỹ bài của người khác.
Code không xóa Module mà chỉ xóa hàm trong Module vì người hỏi viết: "Xin hỏi các chuyên gia có code nào xóa một sub trong module không"
———————–
Bạn viết code buồn cười thật. Sao bạn cứ gọi một code 2 lần kiểu như:
Bạn gọi 1 lần là được:
————
Để bạn làm được các việc đã nêu thì tôi cho bạn những code dưới đây. Chú ý:
1. DeleteProcedureCode không chỉ xóa code của hàm và sub trong Module mà cả code trong UserForm, Sheet1, 2, 3, ThisWorkBook (với CompName = "UserForm1", "Sheet1", "ThisWorkBook")
2. Tôi viết các hàm liệt kê đòi hỏi thông số WorkBook vì tôi muốn viết hàm tổng quát thao tác trên WorkBook bất kỳ (khi có nhiều WorkBook mở cùng lúc) chứ không chỉ trên ActiveWorkBook.
Nếu bạn chỉ cần thao tác trên ActiveWorkBook thôi thì truyền ActiveWorkBook vào thông số.
À, tôi là siwtom chứ không phải là Wistom
Về yêu cầu của bạn là liệt kê và xóa các Function và Sub (macro) thì tôi đã gửi code.
Nhưng tôi muốn sửa 2 code để có thể liệt kê và xóa cả các property procedures (các property procedures Get, Let, Set trong class module)
Dưới đây tôi gửi lại code của Sub / Function. Những chỗ mầu đỏ là được thêm vào, chỗ mầu xanh là sửa (trước đó là vbext_pk_Proc, bây giờ là ProcKind)
Bây giờ thì tôi tin là code thao tác cho Sheet, ThisWorkbook, UserForm, Module và Class Module, tức "trọn gói".
Excel VBA Breaker – 64 bit version
gist.github.com/OlivierHJ/852006307300a938c7f05f357b69922e
You can try this direct VBA approach which doesn't require HEX editing. It will work for any files (*.xls, *.xlsm, *.xlam …).
Tested and works on:
Looking for 64 bit version? See [URL='stackoverflow.com/a/31005696/4342479']this answer
How it works
I will try my best to explain how it works – please excuse my English.
Using the code
Please backup your files first!
code credited to Siwtom (nick name), a Vietnamese developer
Paste this code under the above code in Module1 and run it
Come back to your VBA Projects and enjoy.
I've built upon Đức Thanh Nguyễn's fantastic answer to allow this method to work with 64-bit versions of Excel. I'm running Excel 2010 64-Bit on 64-Bit Windows 7.
Paste this code in Module2 and run it
DISCLAIMER This worked for me and I have documented it here in the hope it will help someone out. I have not fully tested it. Please be sure to save all open files before proceeding with this option.
Edit: this is an updated version of the accepted answer and should work on more office versions. It's tough but let's get this answer to the top!
With my turn, this is built upon kaybee99's excellent answer which is built upon Đức Thanh Nguyễn's fantastic answer to allow this method to work with both 32/64 bit versions of Office.
An overview of what is changed, we avoid push/ret which is limited to 32bit addresses and replace it with mov/jmp reg.
how it works
Paste this code in Module2 and run it
stackoverflow.com/questions/1026483/is-there-a-way-to-crack-the-password-on-an-excel-vba-project/31005696#31005696