 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
mare
Joined: 01 Aug 2008 Posts: 18
|
Posted: Tue Aug 05, 2008 6:20 pm Post subject: |
|
|
Yes, VarSetCapacity was the problem, i solved that.
The only thing that boders me is BinWrite process speed.
On small files works ok but i tried it on 100MB file,
AMD X2 6000+, 2gigs RAM, took about 25 minutes and it wasn't finished.
But this was whole binary crypting, and then i make like this:
| Code: |
BinReadCry(file,data) ;read only 8 bytes
enc := encrypt(data,pw) ;encrypt those 8
BinRead(file,rest) ;read the rest, offset set to 8
finish = %enc%%rest%
BinWrite(encfile,finish) ; write the encrypted file
|
Now, is the a way so i can speed this process a little bit, actualy speed up very much.
I was thinking if there is a way not to read the rest of the file, but only inject the encrypted part, something like editing.
Can this script do the job?
PhiLho's Binary file reading and writing |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4078 Location: Pittsburgh
|
Posted: Tue Aug 05, 2008 7:02 pm Post subject: |
|
|
| For large files you should use the Windows built-in AES encryption. The AHK binary file I/O should be reasonably fast, that is, avoid the conversion to hex, when possible. |
|
| Back to top |
|
 |
mare
Joined: 01 Aug 2008 Posts: 18
|
Posted: Wed Aug 06, 2008 2:04 am Post subject: |
|
|
Encryption is not a problem it is done quickly, but after that BinWrite process is slow.
I didn't use conversion to hex, BinRead returns binary right?
All i did was read binary, encrypt, and write binary. |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4078 Location: Pittsburgh
|
Posted: Wed Aug 06, 2008 2:12 am Post subject: |
|
|
| The functions here handle the data as hex bytes, therefore they are slow for large files. |
|
| Back to top |
|
 |
mare
Joined: 01 Aug 2008 Posts: 18
|
Posted: Wed Aug 06, 2008 2:18 am Post subject: |
|
|
So you are saying that i need to convert to binary and then write the file ?
This proccess is very slow:
| Code: | file = test.rar
res := BinRead(file,data)
file1 = test1.rar
res := BinWrite(file1,data) |
Do i need to do this?
| Code: | file = test.rar
res := BinRead(file,data)
Hex2Bin(b,data)
file1 = test1.rar
res := BinWrite(file1,data) |
|
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4078 Location: Pittsburgh
|
|
| Back to top |
|
 |
mare
Joined: 01 Aug 2008 Posts: 18
|
Posted: Wed Aug 06, 2008 3:45 pm Post subject: |
|
|
Ok this is a complete script, modified a little:
| Code: | #MaxMem 128
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; THIS IS THE PART I HAVE CHANGED ;;;;;;;;;;;;;
file = test.rar ; 100mb file ,we want to write bytes
;FileDelete %file%
;IfNotEqual ErrorLevel,0, MsgBox Can't delete file "%file%"`nErrorLevel = "%ErrorLevel%"
Hex2Bin(b,"000102030405060708090a0b0c0d0e0f00") ;"000102030405060708090a0b0c0d0e0f00" this is hex value that we want to write, but first convert to bin
res := BinWrite(file,b,17) ; 17 ? 17 like write n=17 bytes?
MsgBox ErrorLevel = %ErrorLevel%`nBytes Written = %res%
res := BinRead(file,data)
MsgBox ErrorLevel = %ErrorLevel%`nBytes Read = %res%
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; /// THIS IS THE PART I HAVE CHANGED ;;;;;;;;;;
ExitApp
Bin2Hex(ByRef h, ByRef b, n=0) ; n bytes binary data -> stream of 2-digit hex
{ ; n = 0: all (SetCapacity can be larger than used!)
format = %A_FormatInteger% ; save original integer format
SetFormat Integer, Hex ; for converting bytes to hex
m := VarSetCapacity(b)
If (n < 1 or n > m)
n := m
Address := &b
h =
Loop %n%
{
x := *Address ; get byte in hex
StringTrimLeft x, x, 2 ; remove 0x
x = 0%x% ; pad left
StringRight x, x, 2 ; 2 hex digits
h = %h%%x%
Address++
}
SetFormat Integer, %format% ; restore original format
}
Hex2Bin(ByRef b, h, n=0) ; n hex digit-pairs -> binary data
{ ; n = 0: all. (Only ByRef can handle binaries)
m := Ceil(StrLen(h)/2)
If (n < 1 or n > m)
n := m
Granted := VarSetCapacity(b, n, 0)
IfLess Granted,%n%, {
ErrorLevel = Mem=%Granted%
Return
}
Address := &b
Loop %n%
{
StringLeft x, h, 2
StringTrimLeft h, h, 2
x = 0x%x%
DllCall("RtlFillMemory", "UInt", Address, "UInt", 1, "UChar", x)
Address++
}
}
/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BinWrite ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
| - Open binary file
| - (Over)Write n bytes (n = 0: all)
| - From offset (offset < 0: counted from end)
| - Close file
| (Binary)data -> file[offset + 0..n-1], rest of file unchanged
| Return #bytes actually written
*/ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BinWrite(file, ByRef data, n=0, offset=0)
{
; Open file for WRITE (0x40..), OPEN_ALWAYS (4): creates only if it does not exists
h := DllCall("CreateFile","str",file,"Uint",0x40000000,"Uint",0,"UInt",0,"UInt",4,"Uint",0,"UInt",0)
IfEqual h,-1, SetEnv, ErrorLevel, -1
IfNotEqual ErrorLevel,0,Return,0 ; couldn't create the file
m = 0 ; seek to offset
IfLess offset,0, SetEnv,m,2
r := DllCall("SetFilePointerEx","Uint",h,"Int64",offset,"UInt *",p,"Int",m)
IfEqual r,0, SetEnv, ErrorLevel, -3
IfNotEqual ErrorLevel,0, {
t = %ErrorLevel% ; save ErrorLevel to be returned
DllCall("CloseHandle", "Uint", h)
ErrorLevel = %t% ; return seek error
Return 0
}
m := VarSetCapacity(data) ; get the capacity ( >= used length )
If (n < 1 or n > m)
n := m
result := DllCall("WriteFile","UInt",h,"Str",data,"UInt",n,"UInt *",Written,"UInt",0)
if (!result or Written < n)
ErrorLevel = -3
IfNotEqual ErrorLevel,0, SetEnv,t,%ErrorLevel%
h := DllCall("CloseHandle", "Uint", h)
IfEqual h,-1, SetEnv, ErrorLevel, -2
IfNotEqual t,,SetEnv, ErrorLevel, %t%-%ErrorLevel%
Return Written
}
/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BinRead ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
| - Open binary file
| - Read n bytes (n = 0: file size)
| - From offset (offset < 0: counted from end)
| - Close file
| (Binary)data (replaced) <- file[offset + 0..n-1]
| Return #bytes actually read
*/ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BinRead(file, ByRef data, n=0, offset=0)
{
h := DllCall("CreateFile","Str",file,"Uint",0x80000000,"Uint",3,"UInt",0,"UInt",3,"Uint",0,"UInt",0)
IfEqual h,-1, SetEnv, ErrorLevel, -1
IfNotEqual ErrorLevel,0,Return,0 ; couldn't open the file
m = 0 ; seek to offset
IfLess offset,0, SetEnv,m,2
r := DllCall("SetFilePointerEx","Uint",h,"Int64",offset,"UInt *",p,"Int",m)
IfEqual r,0, SetEnv, ErrorLevel, -3
IfNotEqual ErrorLevel,0, {
t = %ErrorLevel% ; save ErrorLevel to be returned
DllCall("CloseHandle", "Uint", h)
ErrorLevel = %t% ; return seek error
Return 0
}
m := DllCall("GetFileSize","UInt",h,"Int64 *",r)
If (n < 1 or n > m)
n := m
Granted := VarSetCapacity(data, n, 0)
IfLess Granted,%n%, {
ErrorLevel = Mem=%Granted%
Return 0
}
result := DllCall("ReadFile","UInt",h,"Str",data,"UInt",n,"UInt *",Read,"UInt",0)
if (!result or Read < n)
t = -3
IfNotEqual ErrorLevel,0, SetEnv,t,%ErrorLevel%
h := DllCall("CloseHandle", "Uint", h)
IfEqual h,-1, SetEnv, ErrorLevel, -2
IfNotEqual t,,SetEnv, ErrorLevel, %t%-%ErrorLevel%
Return Read
} |
And one more questin, i dont understand the offset.
If this is binary file 000000000000000 ,and i want to ADD 11 into file, if i want to write at begining offset has to be 0, what if i want to write somewhere in the midle or at the end ? offset has to be greater than 0, this method only add bytes, it not modifies them right?
A lot of "if's"
Thanks again for you help, i know i'm borring.  |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4078 Location: Pittsburgh
|
Posted: Wed Aug 06, 2008 4:08 pm Post subject: |
|
|
| If you want to modify data, first you have to read it, change, and write it back. Btw, search the Forum for more recent Bin2Hex and Hex2Bin functions, these are written 3 years ago. AHK has evolved since, and we can have shorter, much faster conversions now. |
|
| Back to top |
|
 |
mare
Joined: 01 Aug 2008 Posts: 18
|
Posted: Wed Aug 06, 2008 5:29 pm Post subject: |
|
|
I think i finaly made it, need more testing but i'll get back with the results.
Thanks again. |
|
| Back to top |
|
 |
mare
Joined: 01 Aug 2008 Posts: 18
|
Posted: Thu Aug 07, 2008 8:33 pm Post subject: |
|
|
| Laszlo wrote: | | You cannot use normal (string) assignments with binary data. It gets truncated at the first NULL byte. Use instead VarSetCapacity and DllCall("RtlMoveMemory"...) |
It looks like this is what exactly happening, and i dont know what to do.
I'm not familiar with DllCall but i allready have VarSetCapacity in your script and script for encryption, it is set to 2048.
I tried to change it but nothing happened.
I think the blowfish encryption is problem also, because when i read 8 bytes, blowfish encrypt and make them 24 bytes, and when i write them thats 12 hex i loose 2 bytes.
This method is fast and good, but this problem i can not solve.
Please help. |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4078 Location: Pittsburgh
|
Posted: Thu Aug 07, 2008 10:40 pm Post subject: |
|
|
| How do you use Blowfish (parameters, dll)? |
|
| Back to top |
|
 |
mare
Joined: 01 Aug 2008 Posts: 18
|
Posted: Fri Aug 08, 2008 1:17 am Post subject: |
|
|
dll 8kb file, i also have one 70kb, but i found a script here wich uses 8kb.
I tried your aes script but i coud not set it properly. |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4078 Location: Pittsburgh
|
Posted: Fri Aug 08, 2008 3:04 am Post subject: |
|
|
| If we don’t know the parameters, we cannot suggest the right call from AHK. A url to the documentation would do... |
|
| Back to top |
|
 |
mare
Joined: 01 Aug 2008 Posts: 18
|
Posted: Fri Aug 08, 2008 9:26 am Post subject: |
|
|
Here is the blow fish script:
| Code: | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
data = 526172211a0700cf9073
pw = password
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pw := encpass(pw)
msgbox %pw%
res := encrypt(data,pw)
msgbox %res%
res := decrypt(res,pw)
msgbox %res%
;used to encrypt a password to make it a lot more secure
EncPass(Key)
{
;VarSetCapacity(Output, 2048)
ATrim = %A_AutoTrim%
AutoTrim, Off
Ret := DllCall("blowfish.dll\Encpass", "str", "aircdll.dll", "str", "Encpass", "str", Key, "Cdecl")
StringTrimLeft, Key, Key, 4
AutoTrim, %ATrim%
Return Key
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Encryption
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Encrypt(Data,Key)
{
;VarSetCapacity(Output, 2048)
ATrim = %A_AutoTrim%
AutoTrim, Off
Output = %Key%%A_Space%%Data%
Ret := DllCall("blowfish.dll\Encrypt", "str", "aircdll.dll", "str", "Encrypt", "str", Output, "Cdecl")
StringTrimLeft, Output, Output, 4
AutoTrim, %ATrim%
Return Output
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Decryption
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Decrypt(Data,Key)
{
;VarSetCapacity(Output, 2048)
ATrim = %A_AutoTrim%
AutoTrim, Off
Output = %Key%%A_Space%%Data%
Ret := DllCall("blowfish.dll\Decrypt", "str", "aircdll.dll", "str", "Decrypt", "str", Output, "Cdecl")
StringTrimLeft, Output, Output, 4
AutoTrim, %ATrim%
Return Output
} |
All i did was, first read data from file, use this and return data to file. |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4078 Location: Pittsburgh
|
Posted: Fri Aug 08, 2008 4:03 pm Post subject: |
|
|
In the function definition EncPass(Key) you process the key. If the result is not text, the instruction StringTrimLeft, Key, Key, 4 would truncate the result. Also, returning it and assigning to pw both truncate the result at the first NUL. If the processed key is not pure text, you have to use ByRef parameters (and the AutoTrim directive is superfluous).
It is the same in Encrypt and Decrypt, with the variable Output. If it is binary, don’t use StringTrimLeft, do not return Output, and do not use assignments (res := ...). As I said, if you need a copy of the result, do it explicitly with DllCall("RtlMoveMemory", Uint,destination_address, UInt,source_address, Uint,length_in_bytes). With manipulation of the source_address (+4) and the length_in_bytes value you can have the StringTrimLeft effect. |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|