hardsploit_gui 2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +22 -0
- data/Rakefile +1 -0
- data/bin/hardsploit_gui +3 -0
- data/lib/Firmware/FPGA/I2C/I2C_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_I2C_INTERACT.rpd +0 -0
- data/lib/Firmware/FPGA/PARALLEL/NO_MUX_PARALLEL_MEMORY/HARDSPLOIT_FIRMWARE_FPGA_NO_MUX_PARALLEL_MEMORY.rpd +0 -0
- data/lib/Firmware/FPGA/SPI/SPI_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_SPI_INTERACT.rpd +0 -0
- data/lib/Firmware/FPGA/SWD/SWD_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_SWD_INTERACT.rpd +0 -0
- data/lib/Firmware/FPGA/TEST/TEST_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_TEST_INTERACT.rpd +0 -0
- data/lib/Firmware/FPGA/VersionFPGA.rb +5 -0
- data/lib/Firmware/UC/HARDSPLOIT_FIRMWARE_UC.bin +0 -0
- data/lib/Firmware/UC/VersionUC.rb +12 -0
- data/lib/HardsploitAPI/HardsploitAPI.rb +134 -0
- data/lib/HardsploitAPI/HardsploitAPI_CONSTANT.rb +145 -0
- data/lib/HardsploitAPI/HardsploitAPI_FIRMWARE.rb +311 -0
- data/lib/HardsploitAPI/HardsploitAPI_I2C.rb +218 -0
- data/lib/HardsploitAPI/HardsploitAPI_NO_MUX_PARALLELE_MEMORY.rb +229 -0
- data/lib/HardsploitAPI/HardsploitAPI_SPI.rb +179 -0
- data/lib/HardsploitAPI/HardsploitAPI_TEST_INTERACT.rb +98 -0
- data/lib/HardsploitAPI/HardsploitAPI_USB_COMMUNICATION.rb +149 -0
- data/lib/HardsploitAPI/LICENSE.txt +674 -0
- data/lib/HardsploitAPI/README.md +22 -0
- data/lib/HardsploitAPI/SWD/HardsploitAPI_SWD.rb +249 -0
- data/lib/HardsploitAPI/SWD/HardsploitAPI_SWD_DEBUG.rb +102 -0
- data/lib/HardsploitAPI/SWD/HardsploitAPI_SWD_MEM_AP.rb +78 -0
- data/lib/HardsploitAPI/SWD/HardsploitAPI_SWD_STM32.rb +104 -0
- data/lib/HardsploitAPI/TRADEMARK +3 -0
- data/lib/LICENSE.txt +674 -0
- data/lib/README.md +22 -0
- data/lib/TRADEMARK +3 -0
- data/lib/class/Chip_editor.rb +448 -0
- data/lib/class/Command_editor.rb +268 -0
- data/lib/class/Command_table.rb +239 -0
- data/lib/class/Console.rb +28 -0
- data/lib/class/Export_manager.rb +124 -0
- data/lib/class/Firmware.rb +29 -0
- data/lib/class/Generic_commands.rb +275 -0
- data/lib/class/HardsploitGUI.rb +462 -0
- data/lib/class/I2C/I2c_command.rb +48 -0
- data/lib/class/I2C/I2c_export.rb +121 -0
- data/lib/class/I2C/I2c_import.rb +92 -0
- data/lib/class/I2C/I2c_settings.rb +117 -0
- data/lib/class/PARALLEL/Parallel_export.rb +146 -0
- data/lib/class/PARALLEL/Parallel_import.rb +88 -0
- data/lib/class/PARALLEL/Parallel_settings.rb +102 -0
- data/lib/class/SPI/Spi_export.rb +141 -0
- data/lib/class/SPI/Spi_import.rb +112 -0
- data/lib/class/SPI/Spi_settings.rb +90 -0
- data/lib/class/Wire_helper.rb +246 -0
- data/lib/db/associations.rb +125 -0
- data/lib/db/hs.db +0 -0
- data/lib/gui/gui_chip_editor.rb +355 -0
- data/lib/gui/gui_chip_management.rb +372 -0
- data/lib/gui/gui_command_editor.rb +218 -0
- data/lib/gui/gui_export_manager.rb +93 -0
- data/lib/gui/gui_generic_commands.rb +164 -0
- data/lib/gui/gui_generic_export.rb +148 -0
- data/lib/gui/gui_generic_import.rb +126 -0
- data/lib/gui/gui_i2c_command.rb +115 -0
- data/lib/gui/gui_i2c_settings.rb +201 -0
- data/lib/gui/gui_parallel_settings.rb +194 -0
- data/lib/gui/gui_spi_import.rb +126 -0
- data/lib/gui/gui_spi_settings.rb +187 -0
- data/lib/gui/gui_wire_helper.rb +99 -0
- data/lib/gui_designer/gui_chip_editor.ui +553 -0
- data/lib/gui_designer/gui_chip_management.ui +842 -0
- data/lib/gui_designer/gui_command_editor.ui +347 -0
- data/lib/gui_designer/gui_export_manager.ui +115 -0
- data/lib/gui_designer/gui_generic_commands.ui +258 -0
- data/lib/gui_designer/gui_generic_export.ui +179 -0
- data/lib/gui_designer/gui_generic_import.ui +142 -0
- data/lib/gui_designer/gui_i2c_command.ui +145 -0
- data/lib/gui_designer/gui_i2c_settings.ui +261 -0
- data/lib/gui_designer/gui_parallel_settings.ui +244 -0
- data/lib/gui_designer/gui_processing.ui +81 -0
- data/lib/gui_designer/gui_spi_settings.ui +321 -0
- data/lib/gui_designer/gui_wire_helper.ui +117 -0
- data/lib/hardsploit.rb +122 -0
- data/lib/images/search.png +0 -0
- data/lib/logs/error.log +0 -0
- metadata +236 -0
@@ -0,0 +1,218 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#===================================================
|
3
|
+
# Hardsploit API - By Opale Security
|
4
|
+
# www.opale-security.com || www.hardsploit.io
|
5
|
+
# License: GNU General Public License v3
|
6
|
+
# License URI: http://www.gnu.org/licenses/gpl.txt
|
7
|
+
#===================================================
|
8
|
+
|
9
|
+
class HardsploitAPI
|
10
|
+
public
|
11
|
+
# Interact with I2C bus
|
12
|
+
# * +speed+:: I2C::KHZ_100 , I2C::KHZ_400 , I2C::KHZ_1000
|
13
|
+
# * +payload+:: payload to send
|
14
|
+
def i2c_Interact(*args)
|
15
|
+
parametters = HardsploitAPI.checkParametters(["speed","payload"],args)
|
16
|
+
speed = parametters[:speed]
|
17
|
+
payload = parametters[:payload]
|
18
|
+
|
19
|
+
if (speed < 0) and (speed >3) then
|
20
|
+
raise TypeError, 'Speed must be between 0 and 3'
|
21
|
+
end
|
22
|
+
|
23
|
+
if (payload.size > 4000) then
|
24
|
+
raise TypeError, 'Size of the data need to be less than 4000'
|
25
|
+
end
|
26
|
+
|
27
|
+
packet = Array.new
|
28
|
+
packet.push 0 #low byte of lenght of trame refresh automaticly before send by usb
|
29
|
+
packet.push 0 #high byte of lenght of trame refresh automaticly before send by usb
|
30
|
+
packet.push HardsploitAPI.lowByte(USB_COMMAND::FPGA_COMMAND)
|
31
|
+
packet.push HardsploitAPI.highByte(USB_COMMAND::FPGA_COMMAND)
|
32
|
+
|
33
|
+
packet.push 0x50 #Command RAW COMMUNICATION TO FPGA FIFO
|
34
|
+
|
35
|
+
packet.push speed #Add speed
|
36
|
+
packet.concat payload #Add data
|
37
|
+
|
38
|
+
sendPacket packet
|
39
|
+
|
40
|
+
tmp= receiveDATA(2000)
|
41
|
+
case tmp
|
42
|
+
when HardsploitAPI::USB_STATE::BUSY
|
43
|
+
return USB_STATE::BUSY
|
44
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
45
|
+
return USB_STATE::TIMEOUT_RECEIVE
|
46
|
+
else
|
47
|
+
#remove header (4 bytes 2 for size 2 for type of command)
|
48
|
+
return tmp.bytes.drop(4)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Start I2C scan to find addresses
|
53
|
+
# * +speed+:: I2C::KHZ_100 , I2C::KHZ_400 , I2C::KHZ_1000
|
54
|
+
# * Return An array 256 value for each addresse if 0 not present if 1 present
|
55
|
+
def i2c_Scan(*args)
|
56
|
+
parametters = HardsploitAPI.checkParametters(["speed"],args)
|
57
|
+
speed = parametters[:speed]
|
58
|
+
|
59
|
+
if (speed < 0) and (speed >3) then
|
60
|
+
raise TypeError, 'Speed must be between 0 and 3'
|
61
|
+
end
|
62
|
+
|
63
|
+
array_i2c_scan = Array.new
|
64
|
+
result_scan = Array.new
|
65
|
+
return_scan = Array.new
|
66
|
+
|
67
|
+
#we want scan just read address it is a partial scan (fastest)
|
68
|
+
for i in (1..255).step(2) do
|
69
|
+
array_i2c_scan.push HardsploitAPI.lowByte(1) #Count Low Byte
|
70
|
+
array_i2c_scan.push HardsploitAPI.highByte(1) #Count High Byte
|
71
|
+
array_i2c_scan.push i
|
72
|
+
end
|
73
|
+
|
74
|
+
result_scan = i2c_Interact(speed,array_i2c_scan)
|
75
|
+
if result_scan.size != 256 then
|
76
|
+
raise TypeError, "FPGA send a wrong I2C scan result, try again , check power jumper, fix wiring , power on ? (reboot the board if needed)"
|
77
|
+
end
|
78
|
+
|
79
|
+
for i in (0..result_scan.size-1).step(2) do
|
80
|
+
#Check if ACK_ERROR
|
81
|
+
if result_scan[i] == 1 then
|
82
|
+
return_scan.push 1 #For write
|
83
|
+
return_scan.push 1 #For read
|
84
|
+
else
|
85
|
+
return_scan.push 0 #For write
|
86
|
+
return_scan.push 0 #For read
|
87
|
+
end
|
88
|
+
end
|
89
|
+
return return_scan
|
90
|
+
end
|
91
|
+
|
92
|
+
# Interact with I2C bus
|
93
|
+
# * +speed+:: I2C::KHZ_100 , I2C::KHZ_400 , I2C::KHZ_1000
|
94
|
+
# * +i2cBaseAddress+:: I2C base address / Write address (8bits)
|
95
|
+
# * +startAddress+:: Start address (included)
|
96
|
+
# * +stopAddress+:: Stop address (included)
|
97
|
+
# * +sizeMax+:: Size max of memory (important to calculate automaticly the number of byte to set address)
|
98
|
+
def i2c_Generic_Dump (*args)
|
99
|
+
parametters = HardsploitAPI.checkParametters(["speed","i2cBaseAddress","startAddress","stopAddress","sizeMax"],args)
|
100
|
+
speed = parametters[:speed]
|
101
|
+
i2cBaseAddress = parametters[:i2cBaseAddress]
|
102
|
+
startAddress = parametters[:startAddress]
|
103
|
+
stopAddress = parametters[:stopAddress]
|
104
|
+
sizeMax = parametters[:sizeMax]
|
105
|
+
|
106
|
+
if ((startAddress < 0) or (startAddress > sizeMax-1)) then
|
107
|
+
raise TypeError, "Start address can't be negative and not more than size max - 1"
|
108
|
+
end
|
109
|
+
if ((stopAddress < 0) or (stopAddress > (sizeMax-1))) then
|
110
|
+
raise TypeError, "Stop address can't be negative and not more than size max-1 because start at 0"
|
111
|
+
end
|
112
|
+
|
113
|
+
if (stopAddress <= startAddress) then
|
114
|
+
raise TypeError, "Stop address need to be greater than start address"
|
115
|
+
end
|
116
|
+
|
117
|
+
numberOfByteAddress = (((Math.log(sizeMax-1,2)).floor + 1) / 8.0).ceil
|
118
|
+
if numberOfByteAddress > 4 then
|
119
|
+
raise TypeError, "Size max must be less than 2^32 about 4Gb"
|
120
|
+
end
|
121
|
+
|
122
|
+
if numberOfByteAddress <= 0 then
|
123
|
+
raise TypeError, "There is an issue with calculating of number of byte needed"
|
124
|
+
end
|
125
|
+
|
126
|
+
packet_size = 2000 - numberOfByteAddress - 1
|
127
|
+
number_complet_packet = ( (stopAddress-startAddress+1) / packet_size).floor
|
128
|
+
size_last_packet = (stopAddress-startAddress+1) % packet_size
|
129
|
+
|
130
|
+
#SEND the first complete trame
|
131
|
+
for i in 0..number_complet_packet-1 do
|
132
|
+
packet = generate_i2c_read_command i2cBaseAddress,numberOfByteAddress+startAddress,i*packet_size,packet_size
|
133
|
+
|
134
|
+
temp = i2c_Interact(speed,packet)
|
135
|
+
case temp
|
136
|
+
when HardsploitAPI::USB_STATE::PACKET_IS_TOO_LARGE
|
137
|
+
puts "PACKET_IS_TOO_LARGE max: #{HardsploitAPI::USB::USB_TRAME_SIZE}"
|
138
|
+
when HardsploitAPI::USB_STATE::ERROR_SEND
|
139
|
+
puts "ERROR_SEND\n"
|
140
|
+
when HardsploitAPI::USB_STATE::BUSY
|
141
|
+
puts "BUSY"
|
142
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
143
|
+
puts "TIMEOUT_RECEIVE\n"
|
144
|
+
else
|
145
|
+
#Remove header, result of read command and numberOfByte Address too
|
146
|
+
consoleData ( process_dump_i2c_result( temp ) )
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
packet = generate_i2c_read_command i2cBaseAddress,numberOfByteAddress,number_complet_packet*packet_size+startAddress,size_last_packet
|
151
|
+
temp = i2c_Interact(speed,packet)
|
152
|
+
case temp
|
153
|
+
when HardsploitAPI::USB_STATE::PACKET_IS_TOO_LARGE
|
154
|
+
puts "PACKET_IS_TOO_LARGE max: #{HardsploitAPI::USB::USB_TRAME_SIZE}"
|
155
|
+
when HardsploitAPI::USB_STATE::ERROR_SEND
|
156
|
+
puts "ERROR_SEND\n"
|
157
|
+
when HardsploitAPI::USB_STATE::BUSY
|
158
|
+
puts "BUSY"
|
159
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
160
|
+
puts "TIMEOUT_RECEIVE\n"
|
161
|
+
else
|
162
|
+
#Remove header, result of read command and numberOfByte Address too
|
163
|
+
consoleData ( process_dump_i2c_result ( temp ) )
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
def process_dump_i2c_result (packet)
|
169
|
+
result = Array.new
|
170
|
+
for i in (0..packet.size-1).step(2) do
|
171
|
+
case packet[i]
|
172
|
+
when 1 #Read ACK
|
173
|
+
#Save read data
|
174
|
+
result.push packet[i+1]
|
175
|
+
when 0 #Write ACK
|
176
|
+
#Do nothing,don't save write ack
|
177
|
+
else
|
178
|
+
raise TypeError, "Error in I2C transaction, I2C dump seems to be wrong"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
return result
|
182
|
+
end
|
183
|
+
|
184
|
+
def generate_i2c_read_command ( i2cBaseAddress, numberOfByteAddress,startAddress,size)
|
185
|
+
packet = Array.new
|
186
|
+
#Push write command for start address
|
187
|
+
packet.push HardsploitAPI.lowByte(numberOfByteAddress) #size of write command
|
188
|
+
packet.push HardsploitAPI.highByte(numberOfByteAddress) #size of write command
|
189
|
+
|
190
|
+
packet.push i2cBaseAddress #push Write address
|
191
|
+
|
192
|
+
case numberOfByteAddress
|
193
|
+
when 1
|
194
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
195
|
+
when 2
|
196
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
197
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart
|
198
|
+
when 3
|
199
|
+
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
200
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
201
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
202
|
+
when 4
|
203
|
+
packet.push ((startAddress & 0xFF000000) >> 24 ) #AddStart3
|
204
|
+
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
205
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
206
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
207
|
+
else
|
208
|
+
raise TypeError, "Issue in generate_spi_read_command function when parse number of byte address"
|
209
|
+
end
|
210
|
+
|
211
|
+
#Push read command to read size data
|
212
|
+
packet.push HardsploitAPI.lowByte(size) #size of read command
|
213
|
+
packet.push HardsploitAPI.highByte(size) #size of read command
|
214
|
+
packet.push i2cBaseAddress+1 #push read address
|
215
|
+
|
216
|
+
return packet
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,229 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#===================================================
|
3
|
+
# Hardsploit API - By Opale Security
|
4
|
+
# www.opale-security.com || www.hardsploit.io
|
5
|
+
# License: GNU General Public License v3
|
6
|
+
# License URI: http://www.gnu.org/licenses/gpl.txt
|
7
|
+
#===================================================
|
8
|
+
|
9
|
+
class HardsploitAPI
|
10
|
+
public
|
11
|
+
|
12
|
+
|
13
|
+
def readManufactuerCodeMemory
|
14
|
+
write_command_Memory_WithoutMultiplexing(0x00000000,0x90) #ReadDeviceIdentifierCommand
|
15
|
+
return readByteFromMemory(1) #Read from 1 to 1 = read 1 byte at 1
|
16
|
+
end
|
17
|
+
|
18
|
+
def readDeviceIdMemory
|
19
|
+
write_command_Memory_WithoutMultiplexing(0x00000000,0x90) #ReadDeviceIdentifierCommand
|
20
|
+
return readByteFromMemory(0)#Read 0
|
21
|
+
end
|
22
|
+
|
23
|
+
def writeByteToMemory(address,value)
|
24
|
+
#Write data in word mode and read Five status register
|
25
|
+
write_command_Memory_WithoutMultiplexing(address,0x0040)
|
26
|
+
write_command_Memory_WithoutMultiplexing(address,value)
|
27
|
+
return readByteFromMemory(0)
|
28
|
+
end
|
29
|
+
|
30
|
+
def readMode
|
31
|
+
#go in read mode
|
32
|
+
write_command_Memory_WithoutMultiplexing(0x000000,0x00FF)
|
33
|
+
end
|
34
|
+
|
35
|
+
def eraseBlockMemory(blockAddress)
|
36
|
+
#Read Five Word
|
37
|
+
write_command_Memory_WithoutMultiplexing(blockAddress,0x0020) #Block erase command
|
38
|
+
statut = write_command_Memory_WithoutMultiplexing(blockAddress,0x00D0) #Confirm Block erase command
|
39
|
+
|
40
|
+
timeout = 10
|
41
|
+
# while (statut != 128 ) && (timeout >= 0)
|
42
|
+
#
|
43
|
+
# puts "#{statut} #{timeout}"
|
44
|
+
# statut = readByteFromMemory(0) #read statut register
|
45
|
+
# sleep(100)
|
46
|
+
# if timeout == 0 then
|
47
|
+
# return statut
|
48
|
+
# else
|
49
|
+
# timeout = timeout-1
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
for ty in 0..4
|
53
|
+
puts readByteFromMemory(0)
|
54
|
+
end
|
55
|
+
|
56
|
+
puts "Return timeout"
|
57
|
+
return statut
|
58
|
+
end
|
59
|
+
|
60
|
+
def clearStatusRegisterOfMemory
|
61
|
+
#Clear Statut register
|
62
|
+
write_command_Memory_WithoutMultiplexing(0x000000,0x50)
|
63
|
+
end
|
64
|
+
|
65
|
+
def unlockBlock (blockAddress)
|
66
|
+
write_command_Memory_WithoutMultiplexing(blockAddress,0x0060) #Lock Block Command
|
67
|
+
write_command_Memory_WithoutMultiplexing(blockAddress,0x00D0) #UnLock Command
|
68
|
+
return readByteFromMemory(0x000000) #read statut register
|
69
|
+
end
|
70
|
+
|
71
|
+
def write_command_Memory_WithoutMultiplexing(address,data)
|
72
|
+
packet = Array.new
|
73
|
+
packet.push 0 #low byte of lenght of trame refresh automaticly before send by usb
|
74
|
+
packet.push 0 #high byte of lenght of trame refresh automaticly before send by usb
|
75
|
+
packet.push HardsploitAPI.lowByte(USB_COMMAND::FPGA_COMMAND)
|
76
|
+
packet.push HardsploitAPI.highByte(USB_COMMAND::FPGA_COMMAND)
|
77
|
+
|
78
|
+
packet.push 0x50 #Command RAW COMMUNICATION TO FPGA FIFO
|
79
|
+
|
80
|
+
packet.push 0 #16 bits
|
81
|
+
packet.push (1500/6.66).floor #latency at 1500ns
|
82
|
+
|
83
|
+
packet.push ((address & 0xFF000000) >> 24 ) #AddStart3
|
84
|
+
packet.push ((address & 0x00FF0000) >> 16 ) #AddStart2
|
85
|
+
packet.push ((address & 0x0000FF00) >> 8 ) #AddStart1
|
86
|
+
packet.push ((address & 0x000000FF) >> 0) #AddStart0
|
87
|
+
packet.push 0x20 #Memory write command
|
88
|
+
packet.push ((data & 0xFF00) >> 8 ) #Data HIGHT BYTE
|
89
|
+
packet.push ((data & 0xFF) >> 0) #Data LOW BYTE
|
90
|
+
|
91
|
+
|
92
|
+
result = sendAndReceiveDATA(packet,1000)
|
93
|
+
if result == USB_STATE::TIMEOUT_RECEIVE then
|
94
|
+
raise "TIMEOUT"
|
95
|
+
elsif result[4] == (data & 0xFF)
|
96
|
+
|
97
|
+
return readByteFromMemory(0)
|
98
|
+
else
|
99
|
+
raise "ERROR BAD RESPONSE"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def readByteFromMemory(address)
|
104
|
+
packet = Array.new
|
105
|
+
packet.push 0 #low byte of lenght of trame refresh automaticly before send by usb
|
106
|
+
packet.push 0 #high byte of lenght of trame refresh automaticly before send by usb
|
107
|
+
packet.push HardsploitAPI.lowByte(USB_COMMAND::FPGA_COMMAND)
|
108
|
+
packet.push HardsploitAPI.highByte(USB_COMMAND::FPGA_COMMAND)
|
109
|
+
|
110
|
+
packet.push 0x50 #Command RAW COMMUNICATION TO FPGA FIFO
|
111
|
+
|
112
|
+
|
113
|
+
#16 bits
|
114
|
+
packet.push 0
|
115
|
+
packet.push (1500/6.66).floor
|
116
|
+
|
117
|
+
|
118
|
+
packet.push ((address & 0xFF000000) >> 24 ) #AddStart3
|
119
|
+
packet.push ((address & 0x00FF0000) >> 16 ) #AddStart2
|
120
|
+
packet.push ((address & 0x0000FF00) >> 8 ) #AddStart1
|
121
|
+
packet.push ((address & 0x000000FF) >> 0) #AddStart0
|
122
|
+
|
123
|
+
packet.push 0x10 #Memory read command
|
124
|
+
packet.push ((address & 0xFF000000) >> 24 ) #AddStart3
|
125
|
+
packet.push ((address & 0x00FF0000) >> 16 ) #AddStop2
|
126
|
+
packet.push ((address & 0x0000FF00) >> 8 ) #AddStop1
|
127
|
+
packet.push ((address & 0x000000FF) >> 0) #AddStop0
|
128
|
+
|
129
|
+
result = sendAndReceiveDATA(packet,1000)
|
130
|
+
|
131
|
+
if result == USB_STATE::TIMEOUT_RECEIVE then
|
132
|
+
return "TIMEOUT"
|
133
|
+
else
|
134
|
+
if result.size == 6 then
|
135
|
+
return HardsploitAPI.BytesToInt(result[4] , result[5])
|
136
|
+
else
|
137
|
+
raise "BAD RESPONSE"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
# Read parallele memory in asynchronous mode (blocking function) but callBack data is used to receive packet
|
147
|
+
# * +addressStart+:: 32 bits address
|
148
|
+
# * +addressStop+:: 32 bits address
|
149
|
+
# * +bits8_or_bits16_DataSize+:: 0 for 8 bits operation & 1 for 16 bits operation
|
150
|
+
# * +latency+:: latency in ns range 7ns to 1600ns=1,6ms
|
151
|
+
# Return USB_STATE End with TIMEOUT_RECEIVE but need to check if received the right number of bytes to ensure all is correct
|
152
|
+
def read_Memory_WithoutMultiplexing(*args)
|
153
|
+
parametters = HardsploitAPI.checkParametters(["addressStart","addressStop","bits8_or_bits16_DataSize","latency"],args)
|
154
|
+
addressStart = parametters[:addressStart]
|
155
|
+
addressStop = parametters[:addressStop]
|
156
|
+
bits8_or_bits16_DataSize = parametters[:bits8_or_bits16_DataSize]
|
157
|
+
latency = parametters[:latency]
|
158
|
+
|
159
|
+
|
160
|
+
numberOfByteReaded = 0
|
161
|
+
packet = Array.new
|
162
|
+
packet.push 0 #low byte of lenght of trame refresh automaticly before send by usb
|
163
|
+
packet.push 0 #high byte of lenght of trame refresh automaticly before send by usb
|
164
|
+
packet.push HardsploitAPI.lowByte(USB_COMMAND::FPGA_COMMAND)
|
165
|
+
packet.push HardsploitAPI.highByte(USB_COMMAND::FPGA_COMMAND)
|
166
|
+
|
167
|
+
packet.push 0x50 #Command RAW COMMUNICATION TO FPGA FIFO
|
168
|
+
|
169
|
+
#Chek if 8bits or 16 bits
|
170
|
+
if bits8_or_bits16_DataSize == true then
|
171
|
+
packet.push 1
|
172
|
+
else
|
173
|
+
packet.push 0
|
174
|
+
end
|
175
|
+
|
176
|
+
#Check latency value
|
177
|
+
if ((latency >= 7) and (latency <= 1600)) then
|
178
|
+
packet.push (latency/6.66).floor
|
179
|
+
else
|
180
|
+
raise TypeError, 'Latency value must be from 7 to 1695'
|
181
|
+
end
|
182
|
+
|
183
|
+
#Check address
|
184
|
+
if (addressStop <= addressStart ) then
|
185
|
+
raise TypeError, 'Stop address is less than start address'
|
186
|
+
end
|
187
|
+
|
188
|
+
packet.push ((addressStart & 0xFF000000) >> 24 ) #AddStart3
|
189
|
+
packet.push ((addressStart & 0x00FF0000) >> 16 ) #AddStart2
|
190
|
+
packet.push ((addressStart & 0x0000FF00) >> 8 ) #AddStart1
|
191
|
+
packet.push ((addressStart & 0x000000FF) >> 0) #AddStart0
|
192
|
+
|
193
|
+
packet.push 0x10 #Memory read command
|
194
|
+
packet.push ((addressStop & 0xFF000000) >> 24 ) #AddStart3
|
195
|
+
packet.push ((addressStop & 0x00FF0000) >> 16 ) #AddStop2
|
196
|
+
packet.push ((addressStop & 0x0000FF00) >> 8 ) #AddStop1
|
197
|
+
packet.push ((addressStop & 0x000000FF) >> 0) #AddStop0
|
198
|
+
|
199
|
+
sendPacket(packet)
|
200
|
+
|
201
|
+
if bits8_or_bits16_DataSize then
|
202
|
+
sizeCalculated = (addressStop-addressStart+1)
|
203
|
+
else
|
204
|
+
sizeCalculated = (addressStop-addressStart+1)*2
|
205
|
+
end
|
206
|
+
|
207
|
+
numberOfByteReaded = 0
|
208
|
+
while true
|
209
|
+
tmp= receiveDATA(2000)
|
210
|
+
case tmp
|
211
|
+
when HardsploitAPI::USB_STATE::BUSY
|
212
|
+
raise "USB_STATE::BUSY"
|
213
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
214
|
+
raise "Timeout"
|
215
|
+
else
|
216
|
+
#remove header (4 bytes 2 for size 2 for type of command)
|
217
|
+
tmp = tmp.bytes.drop(4)
|
218
|
+
numberOfByteReaded = numberOfByteReaded + tmp.size
|
219
|
+
consoleData(tmp)
|
220
|
+
|
221
|
+
puts "Receive #{numberOfByteReaded} of #{sizeCalculated}"
|
222
|
+
if numberOfByteReaded >= sizeCalculated then
|
223
|
+
#Exit because we received all data
|
224
|
+
return
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#===================================================
|
3
|
+
# Hardsploit API - By Opale Security
|
4
|
+
# www.opale-security.com || www.hardsploit.io
|
5
|
+
# License: GNU General Public License v3
|
6
|
+
# License URI: http://www.gnu.org/licenses/gpl.txt
|
7
|
+
#===================================================
|
8
|
+
|
9
|
+
class HardsploitAPI
|
10
|
+
public
|
11
|
+
|
12
|
+
# SPI interact
|
13
|
+
# * +mode+:: SPI mode 0,1,2,3
|
14
|
+
# * +speed+:: Range 1-255 SPI clock = 150Mhz / (2*speed) tested from 3 to 255 (25Mhz to about 0.3Khz)
|
15
|
+
# * +payload+:: Byte array want to send
|
16
|
+
# * Return SPI data received
|
17
|
+
def spi_Interact(*args)
|
18
|
+
parametters = HardsploitAPI.checkParametters(["mode","speed","payload"],args)
|
19
|
+
mode = parametters[:mode]
|
20
|
+
speed = parametters[:speed]
|
21
|
+
payload = parametters[:payload]
|
22
|
+
|
23
|
+
if (mode < 0) and (mode >3) then
|
24
|
+
raise TypeError, 'Mode must be between 0 and 3'
|
25
|
+
end
|
26
|
+
if (speed <= 2) and (speed >256) then
|
27
|
+
raise TypeError, 'Speed must be between 3 and 255'
|
28
|
+
end
|
29
|
+
|
30
|
+
if (payload.size > 4000) then
|
31
|
+
raise TypeError, 'Size of the data need to be less than 4000'
|
32
|
+
end
|
33
|
+
|
34
|
+
packet = Array.new
|
35
|
+
packet.push 0 #low byte of lenght of trame refresh automaticly before send by usb
|
36
|
+
packet.push 0 #high byte of lenght of trame refresh automaticly before send by usb
|
37
|
+
packet.push HardsploitAPI.lowByte(USB_COMMAND::FPGA_COMMAND)
|
38
|
+
packet.push HardsploitAPI.highByte(USB_COMMAND::FPGA_COMMAND)
|
39
|
+
|
40
|
+
packet.push 0x50 #Command RAW COMMUNICATION TO FPGA FIFO
|
41
|
+
|
42
|
+
packet.push mode #Add mode
|
43
|
+
packet.push speed #Add speed
|
44
|
+
packet.concat payload #Add data
|
45
|
+
|
46
|
+
sendPacket packet
|
47
|
+
|
48
|
+
tmp= receiveDATA(1000)
|
49
|
+
case tmp
|
50
|
+
when HardsploitAPI::USB_STATE::BUSY
|
51
|
+
return USB_STATE::BUSY
|
52
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
53
|
+
return USB_STATE::TIMEOUT_RECEIVE
|
54
|
+
else
|
55
|
+
#remove header (4 bytes 2 for size 2 for type of command)
|
56
|
+
return tmp.bytes.drop(4)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Spi generic dump
|
61
|
+
# * +mode+:: SPI mode 0,1,2,3
|
62
|
+
# * +speed+:: Range 1-255 SPI clock = 150Mhz / (2*speed) tested from 3 to 255 (25Mhz to about 0.3Khz)
|
63
|
+
# * +readSpiCommand+:: The read command
|
64
|
+
# * +startAddress+:: Start address (included)
|
65
|
+
# * +stopAddress+:: Stop address (included)
|
66
|
+
# * +sizeMax+:: Size max of memory (important to calculate automaticly the number of byte to set address)
|
67
|
+
def spi_Generic_Dump (*args)
|
68
|
+
parametters = HardsploitAPI.checkParametters(["mode","speed","readSpiCommand","startAddress","stopAddress","sizeMax"],args)
|
69
|
+
mode = parametters[:mode]
|
70
|
+
speed = parametters[:speed]
|
71
|
+
readSpiCommand = parametters[:readSpiCommand]
|
72
|
+
startAddress = parametters[:startAddress]
|
73
|
+
stopAddress = parametters[:stopAddress]
|
74
|
+
sizeMax = parametters[:sizeMax]
|
75
|
+
|
76
|
+
if ((startAddress < 0) or (startAddress > sizeMax-1)) then
|
77
|
+
raise TypeError, "Start address can't be negative and not more than size max - 1"
|
78
|
+
end
|
79
|
+
if ((stopAddress < 0) or (stopAddress > (sizeMax-1))) then
|
80
|
+
raise TypeError, "Stop address can't be negative and not more than size max-1 because start at 0"
|
81
|
+
end
|
82
|
+
|
83
|
+
if (stopAddress < startAddress) then
|
84
|
+
raise TypeError, "Stop address need to be greater than start address"
|
85
|
+
end
|
86
|
+
|
87
|
+
numberOfByteAddress = (((Math.log(sizeMax-1,2)).floor + 1) / 8.0).ceil
|
88
|
+
if numberOfByteAddress > 4 then
|
89
|
+
raise TypeError, "Size max must be less than 2^32 about 4Gb"
|
90
|
+
end
|
91
|
+
|
92
|
+
if numberOfByteAddress <= 0 then
|
93
|
+
raise TypeError, "There is an issue with calculating of number of byte needed"
|
94
|
+
end
|
95
|
+
|
96
|
+
packet_size = 4000 - numberOfByteAddress - 1
|
97
|
+
number_complet_packet = ( (stopAddress-startAddress+1) / packet_size).floor
|
98
|
+
size_last_packet = (stopAddress-startAddress+1) % packet_size
|
99
|
+
|
100
|
+
#SEND the first complete trame
|
101
|
+
for i in 0..number_complet_packet-1 do
|
102
|
+
packet = generate_spi_read_command numberOfByteAddress,readSpiCommand,i*packet_size+startAddress,packet_size
|
103
|
+
|
104
|
+
temp = spi_Interact(mode,speed,packet)
|
105
|
+
case temp
|
106
|
+
when HardsploitAPI::USB_STATE::PACKET_IS_TOO_LARGE
|
107
|
+
puts "PACKET_IS_TOO_LARGE max: #{HardsploitAPI::USB::USB_TRAME_SIZE}"
|
108
|
+
when HardsploitAPI::USB_STATE::ERROR_SEND
|
109
|
+
puts "ERROR_SEND\n"
|
110
|
+
when HardsploitAPI::USB_STATE::BUSY
|
111
|
+
puts "BUSY"
|
112
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
113
|
+
puts "TIMEOUT_RECEIVE\n"
|
114
|
+
else
|
115
|
+
#Remove header, result of read command and numberOfByte Address too
|
116
|
+
puts "receive real size #{temp.size}"
|
117
|
+
consoleData temp.drop(numberOfByteAddress+1)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
packet = generate_spi_read_command numberOfByteAddress,readSpiCommand,number_complet_packet*packet_size+startAddress,size_last_packet
|
122
|
+
temp = spi_Interact(mode,speed,packet)
|
123
|
+
case temp
|
124
|
+
when HardsploitAPI::USB_STATE::PACKET_IS_TOO_LARGE
|
125
|
+
puts "PACKET_IS_TOO_LARGE max: #{HardsploitAPI::USB::USB_TRAME_SIZE}"
|
126
|
+
when HardsploitAPI::USB_STATE::ERROR_SEND
|
127
|
+
puts "ERROR_SEND\n"
|
128
|
+
when HardsploitAPI::USB_STATE::BUSY
|
129
|
+
puts "BUSY"
|
130
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
131
|
+
puts "TIMEOUT_RECEIVE\n"
|
132
|
+
else
|
133
|
+
#Remove header, result of read command and numberOfByte Address too
|
134
|
+
puts "receive real size #{temp.size}"
|
135
|
+
consoleData temp.drop(numberOfByteAddress+1)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
protected
|
140
|
+
def generate_spi_read_command ( numberOfByteAddress,readSpiCommand,startAddress,size)
|
141
|
+
packet = Array.new
|
142
|
+
|
143
|
+
#Push read command
|
144
|
+
packet.push readSpiCommand
|
145
|
+
|
146
|
+
case numberOfByteAddress
|
147
|
+
when 1
|
148
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
149
|
+
|
150
|
+
when 2
|
151
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
152
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
153
|
+
|
154
|
+
when 3
|
155
|
+
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
156
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
157
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
158
|
+
|
159
|
+
when 4
|
160
|
+
packet.push ((startAddress & 0xFF000000) >> 24 ) #AddStart3
|
161
|
+
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
162
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
163
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
164
|
+
else
|
165
|
+
raise TypeError, "Issue in generate_spi_read_command function when parse number of byte address"
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
#put N dummy byte to read size data
|
170
|
+
packet.push *Array.new(size, 0)
|
171
|
+
|
172
|
+
puts " Send real size #{packet.size}"
|
173
|
+
if packet.size > 4000 then
|
174
|
+
raise TypeError, "Too many byte to send in spi mode not more than 4000 is needed"
|
175
|
+
end
|
176
|
+
|
177
|
+
return packet
|
178
|
+
end
|
179
|
+
end
|