Benutzer mit den meisten Antworten
Files kopieren anhand von Magic Numbers

Frage
Antworten
-
Da es sehr viele Fileformate gibt (jede Anwendung hat hier eigenes), stehst du wahrlich vor einer Mammutaufgabe, die zudem auch noch unsicher wird.
Seit Jahren/Jahrzenten ist man eigentlich mit Virenscannern (oder Bitdefender wers mag) gut genug gefahren.
Zumal ja jeder Softwareupdate eine andere "Signatur" seiner Dokumente erzeugen kann oder diese auch wiederum vom Inhalt abhängt.
Eine PDF fängt z.B. mit "%PDF" gefolgt von der Version an. Was hindert mich also, in eine Textdatei "%PDF-1.3" reinzuschreiben?Ich glaube, diese Aufgabenstellung solltest du vergessen und wie alle, z.B., robocopy verwenden.
- Als Antwort vorgeschlagen Denniver ReiningMVP, Moderator Freitag, 13. Juli 2018 13:23
- Als Antwort markiert Denniver ReiningMVP, Moderator Montag, 16. Juli 2018 12:58
-
Hmmm .... kann sein, dass ich noch nicht alles verstanden habe, aber wenn Du in Deiner Funktion Get-MagicNumber ganze Verzeichnisse verabeitest, solltest Du nicht nur die Magic Numbers in der Ausgabe haben, sondern auch noch die zugehörigen Dateien, oder? Sonst weißt Du ja gar nicht, auf welche Datei sich welche Magic Number bezieht. Wenn man Deiner Funktion nur einen Pfad übergibt (ohne Dateimaske) dann knirscht es auch gewaltig. Vielleicht schaust Du Dir mal die Hilfe für about_Funtions_advanced_Parameters an.
Best regards,
(79,108,97,102|%{[char]$_})-join''
- Als Antwort vorgeschlagen Denniver ReiningMVP, Moderator Freitag, 13. Juli 2018 13:23
- Als Antwort markiert Denniver ReiningMVP, Moderator Montag, 16. Juli 2018 12:58
Alle Antworten
-
Hallo René, erstmal Willkommen im deutschen Powershell Forum.
Ohne eine Vorstellung davon zu haben, was Magic Numbers sind, würde ich sagen, das sollte kein Problem darstellen.
Vorsorglich möchte ich aber schon mal darauf hinweisen, dass wir hier keinen Code / Scripte auf Bestellung liefern.
Für die meisten Copy-Jobs eignet sich übrigens robocopy ganz hervorragend - da ist häufig gar kein aufwändiges Script notwendig.
Best regards,
(79,108,97,102|%{[char]$_})-join''
-
Das Windowsfilesystem (NTFS) unterstützt keine Magic Numbers. Dies ist ein Begriff aus dem Linux-/Unix-Filesystem.
Mittels Magic Numbers wird i.W. der Typ einer Datei (ausführbar, Text, Script, usw.) festgelegt um die passende Anwendung zu starten.
In Windows wird dafür die Datei-Endung verwendet, wobei eben "exe", "com" als ausführbarer Code gelten und für alles andere eine Anwendung zuständig ist. Diese erkennt dann, ob sie mit dem Inhalt was anfangen kann.
Eine Umbenennung auf Linux führt nicht zur Änderung der Magic Number, eine Umbenennung der Endung auf Windows kann durchaus auch zu katastrophalen Ergebnissen führen (falls ausführbarer Code enthalten ist).
- Bearbeitet Der Suchende Montag, 9. Juli 2018 10:33
-
Hallo BOfH_666
Dank für die rasche Antwort.
Mit Magic Numbers meint ich die File Signaturen
https://en.wikipedia.org/wiki/List_of_file_signatures
Ich bin der Meinung das das eben robocopy nicht kann.
Ich kann die File Signaturen abfragen mit:
$path = "C:\temp\test"
function Get-MagicNumber ($path)
{ Resolve-Path $path | Foreach-Object {
$magicnumber = Get-Content -encoding byte $_ -read 4 -total 4
$hex1 = ("{0:x}" -f ($magicnumber[0] * 256 + $magicnumber[1])).PadLeft(4, "0")
$hex2 = ("{0:x}" -f ($magicnumber[2] * 256 + $magicnumber[3])).PadLeft(4, "0")
[string] $chars = $magicnumber| %{ if ([char]::IsLetterOrDigit($_))
{ [char] $_ } else { "." }}
"{0} {1} '{2}'" -f $hex1, $hex2, $chars }
}
cd C:\temp\test
$path = Get-ChildItem -Path C:\temp\test
Get-MagicNumber $path
$ArrayMN = Get-MagicNumber $path
$ArrayCI = Get-ChildItem -Path C:\temp\test | Select-Object FullnameUnd habe die Werte dann in Variablen.
Gibt es eine möglichkeit die Werte in ein PS Array zu Mergen, so dass ich in diesem wieder Selektiren kann um zu kopieren?
Ich habe es versucht mit:
$ArrayMN = @(Get-MagicNumber $path)
$ArrayCI = @(Get-ChildItem -Path C:\temp\test | Select-Object Fullname)
0..($ArrayCI.Count - 0) | ForEach-Object {$TArray += @("$($ArrayMN[$_]) $($ArrayCI[$_])")}
$TArray | sort | Get-Unique -AsString$RArray = $TArray | Select-String -SimpleMatch "7664 7673 'v d v s'", "4d5a 9000 'M Z . .'", "7361 6661 's a f a'" | sort | Get-Unique -AsString | ft
$RArray | ftAusgabe:
PS C:\temp\test> $RArray = $TArray | Select-String -SimpleMatch "7664 7673 'v d v s'", "4d5a 9000 'M Z . .'", "7361 6661 's a f a'" | sort | Get-Unique -AsString | ft
$RArray | ft
IgnoreCase LineNumber Line Filename Path Pattern Context Matche
s
---------- ---------- ---- -------- ---- ------- ------- ------
True 1 @{FullName=C:\temp\test\cp029814.exe} 4d5a 9000 'M Z . .' InputStream InputStream 4d5a 9000 'M Z . .' {}
True 6 4d5a 9000 'M Z . .' @{FullName=C:\temp\test\cp029814.exe} InputStream InputStream 4d5a 9000 'M Z . .' {}Danach geht das kopieren nicht.
Ich denke das der merge nicht richtig ist.
Gruss
René
-
Hallo
Vielleicht noch was zu unserem Case
Wir wollen Files von einer unsicheren Umbebung in eine sichere Umgebung kopieren.
Der User legt die Dateien (.txt,.pdf und .csv) in einen Ordner auf der unsicheren Seite.
Ein Script soll dann die Dateien auf die Sichere Seite kopieren.
Damit nicht andere Dateitypen (umbennenen der Extention) auf die sichere Seite gelangen können möchten wir noch die File Signaturen (Magic Numbers) überprüfen.
Gruss
René -
Hallo BOfH_666
Dank für die rasche Antwort.
Mit Magic Numbers meint ich die File Signaturen
https://en.wikipedia.org/wiki/List_of_file_signatures
Ich bin der Meinung das das eben robocopy nicht kann.
Ich kann die File Signaturen abfragen mit:
$path = "C:\temp\test"
function Get-MagicNumber ($path)
{ Resolve-Path $path | Foreach-Object {
$magicnumber = Get-Content -encoding byte $_ -read 4 -total 4
$hex1 = ("{0:x}" -f ($magicnumber[0] * 256 + $magicnumber[1])).PadLeft(4, "0")
$hex2 = ("{0:x}" -f ($magicnumber[2] * 256 + $magicnumber[3])).PadLeft(4, "0")
[string] $chars = $magicnumber| %{ if ([char]::IsLetterOrDigit($_))
{ [char] $_ } else { "." }}
"{0} {1} '{2}'" -f $hex1, $hex2, $chars }
}
cd C:\temp\test
$path = Get-ChildItem -Path C:\temp\test
Get-MagicNumber $path
$ArrayMN = Get-MagicNumber $path
$ArrayCI = Get-ChildItem -Path C:\temp\test | Select-Object FullnameUnd habe die Werte dann in Variablen.
Gibt es eine möglichkeit die Werte in ein PS Array zu Mergen, so dass ich in diesem wieder Selektiren kann um zu kopieren?
Ich habe es versucht mit:
$ArrayMN = @(Get-MagicNumber $path)
$ArrayCI = @(Get-ChildItem -Path C:\temp\test | Select-Object Fullname)
0..($ArrayCI.Count - 0) | ForEach-Object {$TArray += @("$($ArrayMN[$_]) $($ArrayCI[$_])")}
$TArray | sort | Get-Unique -AsString$RArray = $TArray | Select-String -SimpleMatch "7664 7673 'v d v s'", "4d5a 9000 'M Z . .'", "7361 6661 's a f a'" | sort | Get-Unique -AsString | ft
$RArray | ftAusgabe:
PS C:\temp\test> $RArray = $TArray | Select-String -SimpleMatch "7664 7673 'v d v s'", "4d5a 9000 'M Z . .'", "7361 6661 's a f a'" | sort | Get-Unique -AsString | ft
$RArray | ft
IgnoreCase LineNumber Line Filename Path Pattern Context Matche
s
---------- ---------- ---- -------- ---- ------- ------- ------
True 1 @{FullName=C:\temp\test\cp029814.exe} 4d5a 9000 'M Z . .' InputStream InputStream 4d5a 9000 'M Z . .' {}
True 6 4d5a 9000 'M Z . .' @{FullName=C:\temp\test\cp029814.exe} InputStream InputStream 4d5a 9000 'M Z . .' {}Danach geht das kopieren nicht.
Ich denke das der merge nicht richtig ist.
Gruss
René
Und poste das nächste mal Code als Code ;-)
- Bearbeitet BeatYa Montag, 9. Juli 2018 12:26
-
Da du deine eigene Magic-Number generierst in dem du die ersten 4 Bytes ausliest, hast du keine Magic-Number sondern die ersten 4 Bytes, die in der Datei stehen.
Wenn ich also eine .TXT erstelle und eine Zeile mit "AA" erfasse, bekommst du 4 Zeichen "AA" + CRLF zurück.
Durch einfaches Ändern von AA in BB bekommst du bereits eine andere Magic-Number.Und dies zieht sich eben durch alle Fileobjekte.
Ändere ich die Dateiendung, ändert sich nur der Dateiname aber nicht der Inhalt. Deine Magic-Number ändert sich also nicht.
Ich weiß also nicht, was du dadurch an Sicherheit gewinnen willst.
-
$path = "C:\temp\test" function Get-MagicNumber ($path) { Resolve-Path $path | Foreach-Object { $magicnumber = Get-Content -encoding byte $_ -read 4 -total 4 $hex1 = ("{0:x}" -f ($magicnumber[0] * 256 + $magicnumber[1])).PadLeft(4, "0") $hex2 = ("{0:x}" -f ($magicnumber[2] * 256 + $magicnumber[3])).PadLeft(4, "0") [string] $chars = $magicnumber| %{ if ([char]::IsLetterOrDigit($_)) { [char] $_ } else { "." }} "{0} {1} '{2}'" -f $hex1, $hex2, $chars } } cd C:\temp\test $path = Get-ChildItem -Path C:\temp\test Get-MagicNumber $path $ArrayMN = Get-MagicNumber $path $ArrayCI = Get-ChildItem -Path C:\temp\test | Select-Object -ExpandProperty Fullname # Arrays zusammenfügen $ArrayMN = @(Get-MagicNumber $path) $ArrayCI = @(Get-ChildItem -Path C:\temp\test | Select-Object -ExpandProperty Fullname) 0..($ArrayCI.Count - 0) | ForEach-Object {$TArray += @("$($ArrayMN[$_]) $($ArrayCI[$_])")} $TArray | sort | Get-Unique -AsString $RArray = $TArray | Select-String -SimpleMatch "7664 7673 'v d v s'", "4d5a 9000 'M Z . .'", "7361 6661 's a f a'" | sort | Get-Unique -AsString | ft $RArray | ft
Ausgabe:
IgnoreCase LineNumber Line Filename Path Pa
tt
er
n
---------- ---------- ---- -------- ---- --
True 1 @{FullName=C:\temp\test\cp029814.exe} 4d5a 9000 'M Z . .' InputStream InputStream 4d
True 6 4d5a 9000 'M Z . .' @{FullName=C:\temp\test\cp029814.exe} InputStream InputStream 4d
True 11 4d5a 9000 'M Z . .' C:\temp\test\cp029814.exe InputStream InputStream 4dDer Filename ist bei der Ausgabe InputSream.
-
Hmmm .... kann sein, dass ich noch nicht alles verstanden habe, aber wenn Du in Deiner Funktion Get-MagicNumber ganze Verzeichnisse verabeitest, solltest Du nicht nur die Magic Numbers in der Ausgabe haben, sondern auch noch die zugehörigen Dateien, oder? Sonst weißt Du ja gar nicht, auf welche Datei sich welche Magic Number bezieht. Wenn man Deiner Funktion nur einen Pfad übergibt (ohne Dateimaske) dann knirscht es auch gewaltig. Vielleicht schaust Du Dir mal die Hilfe für about_Funtions_advanced_Parameters an.
Best regards,
(79,108,97,102|%{[char]$_})-join''
- Als Antwort vorgeschlagen Denniver ReiningMVP, Moderator Freitag, 13. Juli 2018 13:23
- Als Antwort markiert Denniver ReiningMVP, Moderator Montag, 16. Juli 2018 12:58
-
Da es sehr viele Fileformate gibt (jede Anwendung hat hier eigenes), stehst du wahrlich vor einer Mammutaufgabe, die zudem auch noch unsicher wird.
Seit Jahren/Jahrzenten ist man eigentlich mit Virenscannern (oder Bitdefender wers mag) gut genug gefahren.
Zumal ja jeder Softwareupdate eine andere "Signatur" seiner Dokumente erzeugen kann oder diese auch wiederum vom Inhalt abhängt.
Eine PDF fängt z.B. mit "%PDF" gefolgt von der Version an. Was hindert mich also, in eine Textdatei "%PDF-1.3" reinzuschreiben?Ich glaube, diese Aufgabenstellung solltest du vergessen und wie alle, z.B., robocopy verwenden.
- Als Antwort vorgeschlagen Denniver ReiningMVP, Moderator Freitag, 13. Juli 2018 13:23
- Als Antwort markiert Denniver ReiningMVP, Moderator Montag, 16. Juli 2018 12:58
-
?? ... ich könnte mir vorstellen, dass Du das Problem noch nicht ganz verstanden hast (oder ich hab es noch nicht verstanden ;-) ). Willst Du wirklich die "Signaturen" aller erlaubten Datei-Typen manuell in Deinem Script pflegen? Das klingt mir ziemlich aufwändig und fehlerträchtig.
Best regards,
(79,108,97,102|%{[char]$_})-join''
-
Zumal es (außer bie EXE und COM) ja keine Signaturen für Dateiinhalte gibt.
Nimm nur mal die ganzen ausführbaren Dateien mit Macrocode (bat, vbs, js, wsh, ps1, ...).
Die 1. 4 Bytes der 1. Zeile dieser Dateien wäre ja im Prinzip die Signatur nach obiger Magic Number-Methode.
Und dieser Wert wäre aber so was von nicht distinct.