A consequence of the degradation of a system is the lost of knowledge about it. Therefore, the software artifact becomes a black box that performs its duties but we do not know how.
Software reengineering is the process where it is gathered knowledge about a software artefact in order to create other representations of it. These representations can be higher level, like informal documentation or abstract models of the artefact, or at the same level of abstraction, like the rewriting of the artefact in another programming language or restructuring it in the same programming language.
A software reengineering process can generate several representation, first higher level representations for knowledge gathering and later operational representations to have a version that replaces the old system and has lower maintenance costs.
The reengineering process could be seen a simpler software development process because it starts from a formal description of the requirements, the system to be refactored. However, there are a few constraints. First, it is expected that the cost of reengineering a system should be much lower than the cost of developing a system from scratch, which results in the need to use automatic techniques, like source code translations. Second, the reengineering process is not absent of changes in functionalities. Ideally, it is considered that there is a separation between functionality and technology, in the sense that the former is agnostic about the latter, but actually software artefacts result from an interplay between the functionality and the technology.
Refactoring can be seen as a reengineering manual technique which prevents the software artefact from becoming obsolete.