hardsploit_gui 2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +22 -0
  3. data/Rakefile +1 -0
  4. data/bin/hardsploit_gui +3 -0
  5. data/lib/Firmware/FPGA/I2C/I2C_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_I2C_INTERACT.rpd +0 -0
  6. data/lib/Firmware/FPGA/PARALLEL/NO_MUX_PARALLEL_MEMORY/HARDSPLOIT_FIRMWARE_FPGA_NO_MUX_PARALLEL_MEMORY.rpd +0 -0
  7. data/lib/Firmware/FPGA/SPI/SPI_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_SPI_INTERACT.rpd +0 -0
  8. data/lib/Firmware/FPGA/SWD/SWD_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_SWD_INTERACT.rpd +0 -0
  9. data/lib/Firmware/FPGA/TEST/TEST_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_TEST_INTERACT.rpd +0 -0
  10. data/lib/Firmware/FPGA/VersionFPGA.rb +5 -0
  11. data/lib/Firmware/UC/HARDSPLOIT_FIRMWARE_UC.bin +0 -0
  12. data/lib/Firmware/UC/VersionUC.rb +12 -0
  13. data/lib/HardsploitAPI/HardsploitAPI.rb +134 -0
  14. data/lib/HardsploitAPI/HardsploitAPI_CONSTANT.rb +145 -0
  15. data/lib/HardsploitAPI/HardsploitAPI_FIRMWARE.rb +311 -0
  16. data/lib/HardsploitAPI/HardsploitAPI_I2C.rb +218 -0
  17. data/lib/HardsploitAPI/HardsploitAPI_NO_MUX_PARALLELE_MEMORY.rb +229 -0
  18. data/lib/HardsploitAPI/HardsploitAPI_SPI.rb +179 -0
  19. data/lib/HardsploitAPI/HardsploitAPI_TEST_INTERACT.rb +98 -0
  20. data/lib/HardsploitAPI/HardsploitAPI_USB_COMMUNICATION.rb +149 -0
  21. data/lib/HardsploitAPI/LICENSE.txt +674 -0
  22. data/lib/HardsploitAPI/README.md +22 -0
  23. data/lib/HardsploitAPI/SWD/HardsploitAPI_SWD.rb +249 -0
  24. data/lib/HardsploitAPI/SWD/HardsploitAPI_SWD_DEBUG.rb +102 -0
  25. data/lib/HardsploitAPI/SWD/HardsploitAPI_SWD_MEM_AP.rb +78 -0
  26. data/lib/HardsploitAPI/SWD/HardsploitAPI_SWD_STM32.rb +104 -0
  27. data/lib/HardsploitAPI/TRADEMARK +3 -0
  28. data/lib/LICENSE.txt +674 -0
  29. data/lib/README.md +22 -0
  30. data/lib/TRADEMARK +3 -0
  31. data/lib/class/Chip_editor.rb +448 -0
  32. data/lib/class/Command_editor.rb +268 -0
  33. data/lib/class/Command_table.rb +239 -0
  34. data/lib/class/Console.rb +28 -0
  35. data/lib/class/Export_manager.rb +124 -0
  36. data/lib/class/Firmware.rb +29 -0
  37. data/lib/class/Generic_commands.rb +275 -0
  38. data/lib/class/HardsploitGUI.rb +462 -0
  39. data/lib/class/I2C/I2c_command.rb +48 -0
  40. data/lib/class/I2C/I2c_export.rb +121 -0
  41. data/lib/class/I2C/I2c_import.rb +92 -0
  42. data/lib/class/I2C/I2c_settings.rb +117 -0
  43. data/lib/class/PARALLEL/Parallel_export.rb +146 -0
  44. data/lib/class/PARALLEL/Parallel_import.rb +88 -0
  45. data/lib/class/PARALLEL/Parallel_settings.rb +102 -0
  46. data/lib/class/SPI/Spi_export.rb +141 -0
  47. data/lib/class/SPI/Spi_import.rb +112 -0
  48. data/lib/class/SPI/Spi_settings.rb +90 -0
  49. data/lib/class/Wire_helper.rb +246 -0
  50. data/lib/db/associations.rb +125 -0
  51. data/lib/db/hs.db +0 -0
  52. data/lib/gui/gui_chip_editor.rb +355 -0
  53. data/lib/gui/gui_chip_management.rb +372 -0
  54. data/lib/gui/gui_command_editor.rb +218 -0
  55. data/lib/gui/gui_export_manager.rb +93 -0
  56. data/lib/gui/gui_generic_commands.rb +164 -0
  57. data/lib/gui/gui_generic_export.rb +148 -0
  58. data/lib/gui/gui_generic_import.rb +126 -0
  59. data/lib/gui/gui_i2c_command.rb +115 -0
  60. data/lib/gui/gui_i2c_settings.rb +201 -0
  61. data/lib/gui/gui_parallel_settings.rb +194 -0
  62. data/lib/gui/gui_spi_import.rb +126 -0
  63. data/lib/gui/gui_spi_settings.rb +187 -0
  64. data/lib/gui/gui_wire_helper.rb +99 -0
  65. data/lib/gui_designer/gui_chip_editor.ui +553 -0
  66. data/lib/gui_designer/gui_chip_management.ui +842 -0
  67. data/lib/gui_designer/gui_command_editor.ui +347 -0
  68. data/lib/gui_designer/gui_export_manager.ui +115 -0
  69. data/lib/gui_designer/gui_generic_commands.ui +258 -0
  70. data/lib/gui_designer/gui_generic_export.ui +179 -0
  71. data/lib/gui_designer/gui_generic_import.ui +142 -0
  72. data/lib/gui_designer/gui_i2c_command.ui +145 -0
  73. data/lib/gui_designer/gui_i2c_settings.ui +261 -0
  74. data/lib/gui_designer/gui_parallel_settings.ui +244 -0
  75. data/lib/gui_designer/gui_processing.ui +81 -0
  76. data/lib/gui_designer/gui_spi_settings.ui +321 -0
  77. data/lib/gui_designer/gui_wire_helper.ui +117 -0
  78. data/lib/hardsploit.rb +122 -0
  79. data/lib/images/search.png +0 -0
  80. data/lib/logs/error.log +0 -0
  81. 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